From eb4ed1777ff950e53a6d89bf0ff226f4ace80d24 Mon Sep 17 00:00:00 2001 From: kodonnell Date: Wed, 5 Oct 2016 13:41:48 +1300 Subject: [PATCH 01/22] initial work based on graphhopper Measurement.java --- .gitignore | 2 + map-matching.sh | 103 +++++--- matching-tools/pom.xml | 46 ++++ .../matching/tools/Measurement.java | 228 ++++++++++++++++++ pom.xml | 1 + 5 files changed, 346 insertions(+), 34 deletions(-) create mode 100644 matching-tools/pom.xml create mode 100644 matching-tools/src/main/java/com/graphhopper/matching/tools/Measurement.java diff --git a/.gitignore b/.gitignore index b09ca2ad..ca8c75b6 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,5 @@ nbactions.xml .project matching-vaadin/src/main/webapp/ matching-core/build.xml +/map-data/**/* +bin/ diff --git a/map-matching.sh b/map-matching.sh index b7472bfd..d5f615d4 100755 --- a/map-matching.sh +++ b/map-matching.sh @@ -1,51 +1,86 @@ #!/bin/bash +# bail if any errors ... +set -e + if [ "$JAVA_HOME" != "" ]; then - JAVA=$JAVA_HOME/bin/java + JAVA=$JAVA_HOME/bin/java fi if [ "$JAVA" = "" ]; then - JAVA=java + JAVA=java fi echo "using $JAVA" +function set_jar { + local module=$1 + local pattern="matching-$module/target/graphhopper-map-matching-*-dependencies.jar" + if ! ls $pattern > /dev/null 2>&1; then + mvn --projects hmm-lib -DskipTests=true install + mvn --projects matching-$module,matching-core -DskipTests=true install assembly:single + fi + JAR=$(ls matching-$module/target/graphhopper-map-matching-*-dependencies.jar) +} + if [ "$1" = "action=start-server" ]; then - function set_jar_path { - JAR=$(ls matching-web/target/graphhopper-map-matching-web-*-dependencies.jar) - } - - set_jar_path - - if [ ! -f "$JAR" ]; then - mvn --projects hmm-lib -DskipTests=true install - mvn --projects matching-web,matching-core -DskipTests=true install assembly:single - set_jar_path - fi - - ARGS="graph.location=./graph-cache jetty.resourcebase=matching-web/src/main/webapp" - + set_jar "web" + ARGS="graph.location=./graph-cache jetty.resourcebase=matching-web/src/main/webapp" elif [ "$1" = "action=test" ]; then + export MAVEN_OPTS="-Xmx400m -Xms400m" + mvn clean test verify + # return exit code of mvn + exit $? +elif [ "$1" = "action=measurement" ]; then + set_jar "tools" + fname="measurement.$(date +%Y%m%d_%H%M%S)" + ARGS="config=$CONFIG graph.location=$GRAPH datareader.file=$2 prepare.ch.weightings=fastest graph.flag_encoders=car prepare.min_network_size=10000 prepare.min_oneway_network_size=10000" + current_commit=$(git log -n 1 --pretty=oneline | cut -d' ' -f1) + function startMeasurement { + commit_info=$(git log -n 1 --pretty=oneline) + echo -e "\nperforming measurement for commit $current_commit" + "$JAVA" $JAVA_OPTS -cp "$JAR" com.graphhopper.matching.tools.Measurement $ARGS measurement.count=5000 measurement.location="$measurement_fname" measurement.gitinfo="$commit_info" + } - export MAVEN_OPTS="-Xmx400m -Xms400m" - mvn clean test verify - # return exit code of mvn - exit $? - + # use all versions starting from HEAD + last_commits=$3 + if [ -z "$last_commits" ]; then + measurement_fname=$fname + tested_commit=$current_commit + startMeasurement + else + echo "commits (in order tested):" >> $fname + # TODO: check changes are committed? + values=$fname.values + measurement_fname=$fname.tmp + commits=$(git rev-list HEAD -n $last_commits) + first=true + for commit in $commits; do + git checkout $commit -q + git log -n 1 --pretty=oneline >> $fname + mvn --projects matching-tools -DskipTests=true clean install assembly:single + rm -f $measurement_fname + startMeasurement + while read line; do + key=${line%%=*} + value=$(printf "%-10s" ${line##*=}) + if [ "$first" = true ] ; then + echo $key$value >> $values + else + sed -ir "s/($key.*)/\1$value/g" $values + fi + done < $measurement_fname + done + echo -e "\nmeasurements:\n-------------\n" >> $fname + cat $values >> $fname + rm $values + rm $measurement_fname + # revert checkout + git checkout $current_commit + fi else - function set_jar_path { - JAR=$(ls matching-core/target/graphhopper-map-matching-*-dependencies.jar) - } - - set_jar_path - - if [ ! -f "$JAR" ]; then - mvn --projects hmm-lib -DskipTests=true install - mvn --projects matching-core -DskipTests=true install assembly:single - set_jar_path - fi - - ARGS="$@" + set_jar "core" + ARGS="$@" fi exec "$JAVA" $JAVA_OPTS -jar $JAR $ARGS prepare.min_network_size=0 prepare.min_one_way_network_size=0 diff --git a/matching-tools/pom.xml b/matching-tools/pom.xml new file mode 100644 index 00000000..072a8c45 --- /dev/null +++ b/matching-tools/pom.xml @@ -0,0 +1,46 @@ + + 4.0.0 + GraphHopper Map Matching Tools + com.graphhopper + graphhopper-map-matching-tools + 0.8-SNAPSHOT + + com.graphhopper + graphhopper-map-matching-parent + 0.8-SNAPSHOT + + + + com.graphhopper + graphhopper-map-matching-core + ${project.parent.version} + + + + + + maven-compiler-plugin + 3.5.1 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-assembly-plugin + + + + com.graphhopper.matching.tools.Measurement + + + + jar-with-dependencies + + + + + + \ No newline at end of file diff --git a/matching-tools/src/main/java/com/graphhopper/matching/tools/Measurement.java b/matching-tools/src/main/java/com/graphhopper/matching/tools/Measurement.java new file mode 100644 index 00000000..095d8202 --- /dev/null +++ b/matching-tools/src/main/java/com/graphhopper/matching/tools/Measurement.java @@ -0,0 +1,228 @@ +/* + * 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.matching.tools; + +import com.graphhopper.GHRequest; +import com.graphhopper.GHResponse; +import com.graphhopper.GraphHopper; +import com.graphhopper.PathWrapper; +import com.graphhopper.coll.GHBitSet; +import com.graphhopper.matching.LocationIndexMatch; +import com.graphhopper.matching.MapMatching; +import com.graphhopper.matching.MatchResult; +import com.graphhopper.reader.osm.GraphHopperOSM; +import com.graphhopper.routing.util.*; +import com.graphhopper.routing.weighting.Weighting; +import com.graphhopper.storage.Graph; +import com.graphhopper.storage.GraphHopperStorage; +import com.graphhopper.storage.index.LocationIndexTree; +import com.graphhopper.util.*; +import com.graphhopper.util.shapes.BBox; +import com.graphhopper.util.shapes.GHPoint; +import com.graphhopper.util.shapes.GHPoint3D; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.FileWriter; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.List; +import java.util.ArrayList; +import java.util.Date; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Random; +import java.util.TreeMap; + +/** + * @author Peter Karisch + * @author kodonnell + */ +public class Measurement { + private static final Logger logger = LoggerFactory.getLogger(Measurement.class); + private final Map properties = new TreeMap(); + private long seed; + private int count; + + public static void main(String[] strs) { + new Measurement().start(CmdArgs.read(strs)); + } + + // creates properties file in the format key=value + // Every value is one y-value in a separate diagram with an identical x-value for every Measurement.start call + void start(CmdArgs args) { + String graphLocation = args.get("graph.location", ""); + String propLocation = args.get("measurement.location", ""); + if (Helper.isEmpty(propLocation)) + propLocation = "measurement" + new SimpleDateFormat("yyyy-MM-dd_HH_mm_ss").format(new Date()) + ".properties"; + + seed = args.getLong("measurement.seed", 123); + String gitCommit = args.get("measurement.gitinfo", ""); + count = args.getInt("measurement.count", 5000); + + GraphHopper hopper = new GraphHopperOSM(); + hopper.init(args).forDesktop(); + hopper.getCHFactoryDecorator().setDisablingAllowed(true); + hopper.importOrLoad(); + GraphHopperStorage g = hopper.getGraphHopperStorage(); + String vehicleStr = args.get("graph.flag_encoders", "car"); + FlagEncoder encoder = hopper.getEncodingManager().getEncoder(vehicleStr); + Weighting weighting = hopper.getCHFactoryDecorator().getWeightings().get(0); + + + GraphHopperStorage graph = hopper.getGraphHopperStorage(); + LocationIndexMatch locationIndex = new LocationIndexMatch(graph, (LocationIndexTree) hopper.getLocationIndex()); + MapMatching mapMatching = new MapMatching(graph, locationIndex, encoder); + + StopWatch sw = new StopWatch().start(); + try { +// maxNode = g.getNodes(); +// GHBitSet allowedEdges = printGraphDetails(g, vehicleStr); + boolean isCH = false; + printLocationIndexMatchQuery(g, locationIndex); + printTimeOfMapMatchQuery(hopper, mapMatching, g); +// printMiscUnitPerfTests(g, isCH, encoder, count * 100, allowedEdges); +// printLocationIndexQuery(g, hopper.getLocationIndex(), count); + +// printTimeOfRouteQuery(hopper, isCH, count / 20, "routing", vehicleStr, true); + + System.gc(); + +// CHGraph lg = g.getGraph(CHGraph.class, weighting); +// fillAllowedEdges(lg.getAllEdges(), allowedEdges); +// isCH = true; +// printMiscUnitPerfTests(lg, isCH, encoder, count * 100, allowedEdges); +// printTimeOfRouteQuery(hopper, isCH, count, "routingCH", vehicleStr, true); +// printTimeOfRouteQuery(hopper, isCH, count, "routingCH_no_instr", vehicleStr, false); + logger.info("store into " + propLocation); + } catch (Exception ex) { + logger.error("Problem while measuring " + graphLocation, ex); + put("error", ex.toString()); + } finally { + put("measurement.gitinfo", gitCommit); + put("measurement.count", count); + put("measurement.seed", seed); + put("measurement.time", sw.stop().getTime()); + System.gc(); + put("measurement.totalMB", Helper.getTotalMB()); + put("measurement.usedMB", Helper.getUsedMB()); + try { + store(new FileWriter(propLocation), "measurement finish, " + + new Date().toString() + ", " + Constants.BUILD_DATE); + } catch (IOException ex) { + logger.error("Problem while storing properties " + graphLocation + ", " + propLocation, ex); + } + } + } + + + private void printLocationIndexMatchQuery(Graph g, final LocationIndexMatch idx) { + final BBox bbox = g.getBounds(); + final double latDelta = bbox.maxLat - bbox.minLat; + final double lonDelta = bbox.maxLon - bbox.minLon; + final Random rand = new Random(seed); + MiniPerfTest miniPerf = new MiniPerfTest() { + @Override + public int doCalc(boolean warmup, int run) { + double lat = rand.nextDouble() * latDelta + bbox.minLat; + double lon = rand.nextDouble() * lonDelta + bbox.minLon; + int val = idx.findNClosest(lat, lon, EdgeFilter.ALL_EDGES, rand.nextDouble() * 500).size(); + return val; + } + }.setIterations(count).start(); + print("location_index_match", miniPerf); + } + + private void printTimeOfMapMatchQuery(final GraphHopper hopper, final MapMatching mapMatching, Graph g) { + + // pick random endpoints to create a route, then pick random points from the route, + // and then run the random points through map-matching. + final BBox bbox = g.getBounds(); + final double latDelta = bbox.maxLat - bbox.minLat; + final double lonDelta = bbox.maxLon - bbox.minLon; + final Random rand = new Random(seed); + DistanceCalcEarth distCalc = new DistanceCalcEarth(); + mapMatching.setMaxVisitedNodes((int) 1e10); + MiniPerfTest miniPerf = new MiniPerfTest() { + @Override + public int doCalc(boolean warmup, int run) { + boolean foundPath = false; + while (!foundPath) { + double lat0 = rand.nextDouble() * latDelta + bbox.minLat; + double lon0 = rand.nextDouble() * lonDelta + bbox.minLon; + double lat1 = rand.nextDouble() * latDelta + bbox.minLat; + double lon1 = rand.nextDouble() * lonDelta + bbox.minLon; + double sampleProportion = rand.nextDouble(); + GHResponse r = hopper.route(new GHRequest(lat0, lon0, lat1, lon1)); + if (!r.hasErrors()) { + foundPath = true; + long t = 0; + List mock = new ArrayList(); + GHPoint prev = null; + PointList points = r.getBest().getPoints(); + for (GHPoint p : points) { + if (null != prev && rand.nextDouble() < sampleProportion) { + double dx = distCalc.calcDist(prev.lat, prev.lon, p.lat, p.lon); + double speedKPH = rand.nextDouble() * 100; + double dt = (dx / 1000) / speedKPH * 3600000; + t += (long) dt; + mock.add(new GPXEntry(p, t)); + } + } + // now match: + if (mock.size() > 2) { + MatchResult match = mapMatching.doWork(mock); + } + // return something else? + return 0; + } + } + return 0; + } + }.setIterations(count).start(); + print("map_match", miniPerf); + + } + + + void print(String prefix, MiniPerfTest perf) { + logger.info(prefix + ": " + perf.getReport()); + put(prefix + ".sum", perf.getSum()); +// put(prefix+".rms", perf.getRMS()); + put(prefix + ".min", perf.getMin()); + put(prefix + ".mean", perf.getMean()); + put(prefix + ".max", perf.getMax()); + } + + void put(String key, Object val) { + // convert object to string to make serialization possible + properties.put(key, "" + val); + } + + private void store(FileWriter fileWriter, String comment) throws IOException { + fileWriter.append("#" + comment + "\n"); + for (Entry e : properties.entrySet()) { + fileWriter.append(e.getKey()); + fileWriter.append("="); + fileWriter.append(e.getValue()); + fileWriter.append("\n"); + } + fileWriter.flush(); + } +} diff --git a/pom.xml b/pom.xml index 8af04197..975d70e8 100644 --- a/pom.xml +++ b/pom.xml @@ -58,6 +58,7 @@ hmm-lib matching-core matching-web + matching-tools From 8a587be725f859fdbd4a9f605986deba2522e400 Mon Sep 17 00:00:00 2001 From: kodonnell Date: Wed, 5 Oct 2016 13:50:04 +1300 Subject: [PATCH 02/22] getting multiple commits working ... --- .gitignore | 1 + map-matching.sh | 5 +++-- .../java/com/graphhopper/matching/tools/Measurement.java | 8 +++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index ca8c75b6..536baa5f 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ matching-vaadin/src/main/webapp/ matching-core/build.xml /map-data/**/* bin/ +measurement* diff --git a/map-matching.sh b/map-matching.sh index d5f615d4..e289bf26 100755 --- a/map-matching.sh +++ b/map-matching.sh @@ -56,7 +56,7 @@ elif [ "$1" = "action=measurement" ]; then commits=$(git rev-list HEAD -n $last_commits) first=true for commit in $commits; do - git checkout $commit -q + git checkout $commit git log -n 1 --pretty=oneline >> $fname mvn --projects matching-tools -DskipTests=true clean install assembly:single rm -f $measurement_fname @@ -65,8 +65,9 @@ elif [ "$1" = "action=measurement" ]; then key=${line%%=*} value=$(printf "%-10s" ${line##*=}) if [ "$first" = true ] ; then - echo $key$value >> $values + echo printf "%-30s%s" $key $value >> $values else + echo sed -ir "s/($key.*)/\1$value/g" $values sed -ir "s/($key.*)/\1$value/g" $values fi done < $measurement_fname diff --git a/matching-tools/src/main/java/com/graphhopper/matching/tools/Measurement.java b/matching-tools/src/main/java/com/graphhopper/matching/tools/Measurement.java index 095d8202..398196cf 100644 --- a/matching-tools/src/main/java/com/graphhopper/matching/tools/Measurement.java +++ b/matching-tools/src/main/java/com/graphhopper/matching/tools/Measurement.java @@ -115,7 +115,7 @@ void start(CmdArgs args) { logger.error("Problem while measuring " + graphLocation, ex); put("error", ex.toString()); } finally { - put("measurement.gitinfo", gitCommit); +// put("measurement.gitinfo", gitCommit); put("measurement.count", count); put("measurement.seed", seed); put("measurement.time", sw.stop().getTime()); @@ -123,8 +123,7 @@ void start(CmdArgs args) { put("measurement.totalMB", Helper.getTotalMB()); put("measurement.usedMB", Helper.getUsedMB()); try { - store(new FileWriter(propLocation), "measurement finish, " - + new Date().toString() + ", " + Constants.BUILD_DATE); + store(new FileWriter(propLocation)); } catch (IOException ex) { logger.error("Problem while storing properties " + graphLocation + ", " + propLocation, ex); } @@ -215,8 +214,7 @@ void put(String key, Object val) { properties.put(key, "" + val); } - private void store(FileWriter fileWriter, String comment) throws IOException { - fileWriter.append("#" + comment + "\n"); + private void store(FileWriter fileWriter) throws IOException { for (Entry e : properties.entrySet()) { fileWriter.append(e.getKey()); fileWriter.append("="); From d60985be6683954ba289d9454aad6d7ca7d8bb47 Mon Sep 17 00:00:00 2001 From: kodonnell Date: Wed, 5 Oct 2016 13:51:59 +1300 Subject: [PATCH 03/22] getting multiple commits working ... --- map-matching.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/map-matching.sh b/map-matching.sh index e289bf26..cb5db38d 100755 --- a/map-matching.sh +++ b/map-matching.sh @@ -65,7 +65,7 @@ elif [ "$1" = "action=measurement" ]; then key=${line%%=*} value=$(printf "%-10s" ${line##*=}) if [ "$first" = true ] ; then - echo printf "%-30s%s" $key $value >> $values + printf "%-30s%s" $key $value >> $values else echo sed -ir "s/($key.*)/\1$value/g" $values sed -ir "s/($key.*)/\1$value/g" $values From 0b34d2ddc727c65f1a2b47460aa632bf5c651544 Mon Sep 17 00:00:00 2001 From: kodonnell Date: Wed, 5 Oct 2016 14:48:24 +1300 Subject: [PATCH 04/22] ok, seems to be working ... --- map-matching.sh | 45 ++++++++++--------- .../matching/tools/Measurement.java | 15 ------- 2 files changed, 23 insertions(+), 37 deletions(-) diff --git a/map-matching.sh b/map-matching.sh index cb5db38d..79bed996 100755 --- a/map-matching.sh +++ b/map-matching.sh @@ -37,51 +37,52 @@ elif [ "$1" = "action=measurement" ]; then ARGS="config=$CONFIG graph.location=$GRAPH datareader.file=$2 prepare.ch.weightings=fastest graph.flag_encoders=car prepare.min_network_size=10000 prepare.min_oneway_network_size=10000" current_commit=$(git log -n 1 --pretty=oneline | cut -d' ' -f1) function startMeasurement { - commit_info=$(git log -n 1 --pretty=oneline) echo -e "\nperforming measurement for commit $current_commit" - "$JAVA" $JAVA_OPTS -cp "$JAR" com.graphhopper.matching.tools.Measurement $ARGS measurement.count=5000 measurement.location="$measurement_fname" measurement.gitinfo="$commit_info" + echo $measurement_fname + echo "$JAVA" $JAVA_OPTS -cp "$JAR" com.graphhopper.matching.tools.Measurement $ARGS measurement.location="$measurement_fname" + "$JAVA" $JAVA_OPTS -cp "$JAR" com.graphhopper.matching.tools.Measurement $ARGS measurement.location="$measurement_fname" } # use all versions starting from HEAD last_commits=$3 if [ -z "$last_commits" ]; then measurement_fname=$fname - tested_commit=$current_commit startMeasurement else - echo "commits (in order tested):" >> $fname + echo "commits (in order tested):" >> "$fname" # TODO: check changes are committed? - values=$fname.values - measurement_fname=$fname.tmp - commits=$(git rev-list HEAD -n $last_commits) + values=${fname}.values + measurement_fname=${fname}.tmp + commits=$(git rev-list HEAD -n "$last_commits") first=true for commit in $commits; do - git checkout $commit - git log -n 1 --pretty=oneline >> $fname + git checkout "$commit" + git log -n 1 --pretty=oneline >> "$fname" mvn --projects matching-tools -DskipTests=true clean install assembly:single - rm -f $measurement_fname + rm -f "$measurement_fname" startMeasurement - while read line; do + while read -r line; do key=${line%%=*} - value=$(printf "%-10s" ${line##*=}) + value=$(printf "%-20s" "${line##*=}") if [ "$first" = true ] ; then - printf "%-30s%s" $key $value >> $values + printf "%-30s%s\n" "$key" "$value" >> "$values" else - echo sed -ir "s/($key.*)/\1$value/g" $values - sed -ir "s/($key.*)/\1$value/g" $values + sed -ri "s/($key.*)/\1$value/g" "$values" fi - done < $measurement_fname + done < "$measurement_fname" + first=false done - echo -e "\nmeasurements:\n-------------\n" >> $fname - cat $values >> $fname - rm $values - rm $measurement_fname + echo -e "\nmeasurements:\n-------------\n" >> "$fname" + cat "$values" >> "$fname" + rm "$values" + rm "$measurement_fname" # revert checkout - git checkout $current_commit + git checkout "$current_commit" fi + exit 0 else set_jar "core" ARGS="$@" fi -exec "$JAVA" $JAVA_OPTS -jar $JAR $ARGS prepare.min_network_size=0 prepare.min_one_way_network_size=0 +exec "$JAVA" $JAVA_OPTS -jar "$JAR" $ARGS prepare.min_network_size=0 prepare.min_one_way_network_size=0 diff --git a/matching-tools/src/main/java/com/graphhopper/matching/tools/Measurement.java b/matching-tools/src/main/java/com/graphhopper/matching/tools/Measurement.java index 398196cf..8f0bdfd0 100644 --- a/matching-tools/src/main/java/com/graphhopper/matching/tools/Measurement.java +++ b/matching-tools/src/main/java/com/graphhopper/matching/tools/Measurement.java @@ -34,7 +34,6 @@ import com.graphhopper.util.*; import com.graphhopper.util.shapes.BBox; import com.graphhopper.util.shapes.GHPoint; -import com.graphhopper.util.shapes.GHPoint3D; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -92,24 +91,10 @@ void start(CmdArgs args) { StopWatch sw = new StopWatch().start(); try { -// maxNode = g.getNodes(); -// GHBitSet allowedEdges = printGraphDetails(g, vehicleStr); boolean isCH = false; printLocationIndexMatchQuery(g, locationIndex); printTimeOfMapMatchQuery(hopper, mapMatching, g); -// printMiscUnitPerfTests(g, isCH, encoder, count * 100, allowedEdges); -// printLocationIndexQuery(g, hopper.getLocationIndex(), count); - -// printTimeOfRouteQuery(hopper, isCH, count / 20, "routing", vehicleStr, true); - System.gc(); - -// CHGraph lg = g.getGraph(CHGraph.class, weighting); -// fillAllowedEdges(lg.getAllEdges(), allowedEdges); -// isCH = true; -// printMiscUnitPerfTests(lg, isCH, encoder, count * 100, allowedEdges); -// printTimeOfRouteQuery(hopper, isCH, count, "routingCH", vehicleStr, true); -// printTimeOfRouteQuery(hopper, isCH, count, "routingCH_no_instr", vehicleStr, false); logger.info("store into " + propLocation); } catch (Exception ex) { logger.error("Problem while measuring " + graphLocation, ex); From 77818afbc996bbc5b38451d917caffbd97a70c5c Mon Sep 17 00:00:00 2001 From: kodonnell Date: Thu, 6 Oct 2016 11:23:11 +1300 Subject: [PATCH 05/22] tidying up --- map-matching.sh | 18 +++- .../matching/tools/Measurement.java | 98 +++++++++++-------- 2 files changed, 72 insertions(+), 44 deletions(-) diff --git a/map-matching.sh b/map-matching.sh index 79bed996..02632b11 100755 --- a/map-matching.sh +++ b/map-matching.sh @@ -49,12 +49,15 @@ elif [ "$1" = "action=measurement" ]; then measurement_fname=$fname startMeasurement else - echo "commits (in order tested):" >> "$fname" - # TODO: check changes are committed? + # the following checks out the last commits, and tests each one. The code looks a bit + # messier than that, as we merge the results into a single file (to make it easier to + # compare. + echo "commits (in order tested):\n--------------------------\n" >> "$fname" values=${fname}.values measurement_fname=${fname}.tmp commits=$(git rev-list HEAD -n "$last_commits") first=true + empty_pad="" for commit in $commits; do git checkout "$commit" git log -n 1 --pretty=oneline >> "$fname" @@ -67,10 +70,16 @@ elif [ "$1" = "action=measurement" ]; then if [ "$first" = true ] ; then printf "%-30s%s\n" "$key" "$value" >> "$values" else - sed -ri "s/($key.*)/\1$value/g" "$values" + if grep "$key" "$values"; then + sed -ri "s/($key.*)/\1$value/g" "$values" + else + # add a new row, using $empty_pad to get the column in the right place + printf "%-30s%s%s\n" "$key" "$empty_pad" "$value" >> "$values" + fi fi done < "$measurement_fname" first=false + empty_pad=$(printf "%s%-20s" "$empty_pad" "") done echo -e "\nmeasurements:\n-------------\n" >> "$fname" cat "$values" >> "$fname" @@ -79,6 +88,9 @@ elif [ "$1" = "action=measurement" ]; then # revert checkout git checkout "$current_commit" fi + # in either case, echo the file: + echo "" + cat "$fname" exit 0 else set_jar "core" diff --git a/matching-tools/src/main/java/com/graphhopper/matching/tools/Measurement.java b/matching-tools/src/main/java/com/graphhopper/matching/tools/Measurement.java index 8f0bdfd0..edaec6fb 100644 --- a/matching-tools/src/main/java/com/graphhopper/matching/tools/Measurement.java +++ b/matching-tools/src/main/java/com/graphhopper/matching/tools/Measurement.java @@ -20,8 +20,6 @@ import com.graphhopper.GHRequest; import com.graphhopper.GHResponse; import com.graphhopper.GraphHopper; -import com.graphhopper.PathWrapper; -import com.graphhopper.coll.GHBitSet; import com.graphhopper.matching.LocationIndexMatch; import com.graphhopper.matching.MapMatching; import com.graphhopper.matching.MatchResult; @@ -34,10 +32,8 @@ import com.graphhopper.util.*; import com.graphhopper.util.shapes.BBox; import com.graphhopper.util.shapes.GHPoint; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import java.io.FileWriter; import java.io.IOException; import java.text.SimpleDateFormat; @@ -58,49 +54,49 @@ public class Measurement { private final Map properties = new TreeMap(); private long seed; private int count; + private BBox bbox; + private DistanceCalcEarth distCalc = new DistanceCalcEarth(); - public static void main(String[] strs) { + public static void main(String[] strs) throws Exception { new Measurement().start(CmdArgs.read(strs)); } - // creates properties file in the format key=value - // Every value is one y-value in a separate diagram with an identical x-value for every Measurement.start call - void start(CmdArgs args) { + // creates measurement result file in the format = + void start(CmdArgs args) throws Exception { + + // read and initialise arguments: String graphLocation = args.get("graph.location", ""); String propLocation = args.get("measurement.location", ""); - if (Helper.isEmpty(propLocation)) - propLocation = "measurement" + new SimpleDateFormat("yyyy-MM-dd_HH_mm_ss").format(new Date()) + ".properties"; - + if (Helper.isEmpty(propLocation)) { + throw new Exception("You must provide an output location via the 'measurement.location' argument"); + } seed = args.getLong("measurement.seed", 123); - String gitCommit = args.get("measurement.gitinfo", ""); count = args.getInt("measurement.count", 5000); + // create hopper instance GraphHopper hopper = new GraphHopperOSM(); hopper.init(args).forDesktop(); + hopper.getCHFactoryDecorator().setEnabled(true); hopper.getCHFactoryDecorator().setDisablingAllowed(true); hopper.importOrLoad(); - GraphHopperStorage g = hopper.getGraphHopperStorage(); String vehicleStr = args.get("graph.flag_encoders", "car"); FlagEncoder encoder = hopper.getEncodingManager().getEncoder(vehicleStr); - Weighting weighting = hopper.getCHFactoryDecorator().getWeightings().get(0); - - GraphHopperStorage graph = hopper.getGraphHopperStorage(); + bbox = graph.getBounds(); LocationIndexMatch locationIndex = new LocationIndexMatch(graph, (LocationIndexTree) hopper.getLocationIndex()); MapMatching mapMatching = new MapMatching(graph, locationIndex, encoder); + // start tests: StopWatch sw = new StopWatch().start(); try { - boolean isCH = false; - printLocationIndexMatchQuery(g, locationIndex); - printTimeOfMapMatchQuery(hopper, mapMatching, g); + printLocationIndexMatchQuery(locationIndex); + printTimeOfMapMatchQuery(hopper, mapMatching); System.gc(); logger.info("store into " + propLocation); } catch (Exception ex) { logger.error("Problem while measuring " + graphLocation, ex); put("error", ex.toString()); } finally { -// put("measurement.gitinfo", gitCommit); put("measurement.count", count); put("measurement.seed", seed); put("measurement.time", sw.stop().getTime()); @@ -114,10 +110,13 @@ void start(CmdArgs args) { } } } - - private void printLocationIndexMatchQuery(Graph g, final LocationIndexMatch idx) { - final BBox bbox = g.getBounds(); + /** + * Test the performance of finding candidate points for the index (which is run for every GPX + * entry). + * + */ + private void printLocationIndexMatchQuery(final LocationIndexMatch idx) { final double latDelta = bbox.maxLat - bbox.minLat; final double lonDelta = bbox.maxLon - bbox.minLon; final Random rand = new Random(seed); @@ -133,47 +132,65 @@ public int doCalc(boolean warmup, int run) { print("location_index_match", miniPerf); } - private void printTimeOfMapMatchQuery(final GraphHopper hopper, final MapMatching mapMatching, Graph g) { + /** + * Test the time taken for map matching on random routes. Note that this includes the index + * lookups (previous tests), so will be affected by those. Otherwise this is largely testing + * the routing and HMM performance. + */ + private void printTimeOfMapMatchQuery(final GraphHopper hopper, final MapMatching mapMatching) { - // pick random endpoints to create a route, then pick random points from the route, + // pick random start/end points to create a route, then pick random points from the route, // and then run the random points through map-matching. - final BBox bbox = g.getBounds(); final double latDelta = bbox.maxLat - bbox.minLat; final double lonDelta = bbox.maxLon - bbox.minLon; final Random rand = new Random(seed); - DistanceCalcEarth distCalc = new DistanceCalcEarth(); - mapMatching.setMaxVisitedNodes((int) 1e10); + mapMatching.setMaxVisitedNodes((int) 1e10); // need to set this high to handle long gaps MiniPerfTest miniPerf = new MiniPerfTest() { @Override public int doCalc(boolean warmup, int run) { boolean foundPath = false; + + // keep going until we find a path (which we may not for certain start/end points) while (!foundPath) { - double lat0 = rand.nextDouble() * latDelta + bbox.minLat; - double lon0 = rand.nextDouble() * lonDelta + bbox.minLon; - double lat1 = rand.nextDouble() * latDelta + bbox.minLat; - double lon1 = rand.nextDouble() * lonDelta + bbox.minLon; - double sampleProportion = rand.nextDouble(); + + // create random points and find route between: + double lat0 = bbox.minLat + rand.nextDouble() * latDelta; + double lon0 = bbox.minLon + rand.nextDouble() * lonDelta; + double lat1 = bbox.minLat + rand.nextDouble() * latDelta; + double lon1 = bbox.minLon + rand.nextDouble() * lonDelta; GHResponse r = hopper.route(new GHRequest(lat0, lon0, lat1, lon1)); + + // if found, use it for map mathching: if (!r.hasErrors()) { foundPath = true; - long t = 0; - List mock = new ArrayList(); + long time = 0; + double sampleProportion = rand.nextDouble(); GHPoint prev = null; + List mock = new ArrayList(); PointList points = r.getBest().getPoints(); + // loop through points and add (approximately) sampleProportion of them: for (GHPoint p : points) { if (null != prev && rand.nextDouble() < sampleProportion) { + // estimate a reasonable time taken since the last point, so we + // can give the GPXEntry a time. Use the distance between the + // points and a random speed to estimate a time. double dx = distCalc.calcDist(prev.lat, prev.lon, p.lat, p.lon); double speedKPH = rand.nextDouble() * 100; double dt = (dx / 1000) / speedKPH * 3600000; - t += (long) dt; - mock.add(new GPXEntry(p, t)); + time += (long) dt; + // randomise the point lat/lon (i.e. so it's not exactly on the route): + GHPoint randomised = distCalc.projectCoordinate(p.lat, p.lat, 20 * rand.nextDouble(), 360 * rand.nextDouble()); + mock.add(new GPXEntry(randomised, time)); } } - // now match: + // now match, provided there are enough points if (mock.size() > 2) { - MatchResult match = mapMatching.doWork(mock); + mapMatching.doWork(mock); + } else { + foundPath = false; // retry } - // return something else? + + // TODO: do we need to return something non-trivial? return 0; } } @@ -188,7 +205,6 @@ public int doCalc(boolean warmup, int run) { void print(String prefix, MiniPerfTest perf) { logger.info(prefix + ": " + perf.getReport()); put(prefix + ".sum", perf.getSum()); -// put(prefix+".rms", perf.getRMS()); put(prefix + ".min", perf.getMin()); put(prefix + ".mean", perf.getMean()); put(prefix + ".max", perf.getMax()); From 727ad77002d6eb34b66a198cdf061d0c33910435 Mon Sep 17 00:00:00 2001 From: kodonnell Date: Thu, 6 Oct 2016 11:24:50 +1300 Subject: [PATCH 06/22] formatting msg --- map-matching.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/map-matching.sh b/map-matching.sh index 02632b11..8e162e6b 100755 --- a/map-matching.sh +++ b/map-matching.sh @@ -52,7 +52,7 @@ elif [ "$1" = "action=measurement" ]; then # the following checks out the last commits, and tests each one. The code looks a bit # messier than that, as we merge the results into a single file (to make it easier to # compare. - echo "commits (in order tested):\n--------------------------\n" >> "$fname" + echo -e "commits (in order tested):\n--------------------------\n" >> "$fname" values=${fname}.values measurement_fname=${fname}.tmp commits=$(git rev-list HEAD -n "$last_commits") From b08edf8c734b84142e358c01db2a8ec4581dd69e Mon Sep 17 00:00:00 2001 From: kodonnell Date: Thu, 6 Oct 2016 11:31:19 +1300 Subject: [PATCH 07/22] formatting code --- .../matching/tools/Measurement.java | 357 +++++++++--------- 1 file changed, 179 insertions(+), 178 deletions(-) diff --git a/matching-tools/src/main/java/com/graphhopper/matching/tools/Measurement.java b/matching-tools/src/main/java/com/graphhopper/matching/tools/Measurement.java index edaec6fb..dc9d1bf0 100644 --- a/matching-tools/src/main/java/com/graphhopper/matching/tools/Measurement.java +++ b/matching-tools/src/main/java/com/graphhopper/matching/tools/Measurement.java @@ -22,11 +22,8 @@ import com.graphhopper.GraphHopper; import com.graphhopper.matching.LocationIndexMatch; import com.graphhopper.matching.MapMatching; -import com.graphhopper.matching.MatchResult; import com.graphhopper.reader.osm.GraphHopperOSM; import com.graphhopper.routing.util.*; -import com.graphhopper.routing.weighting.Weighting; -import com.graphhopper.storage.Graph; import com.graphhopper.storage.GraphHopperStorage; import com.graphhopper.storage.index.LocationIndexTree; import com.graphhopper.util.*; @@ -36,10 +33,8 @@ import org.slf4j.LoggerFactory; import java.io.FileWriter; import java.io.IOException; -import java.text.SimpleDateFormat; import java.util.List; import java.util.ArrayList; -import java.util.Date; import java.util.Map; import java.util.Map.Entry; import java.util.Random; @@ -50,178 +45,184 @@ * @author kodonnell */ public class Measurement { - private static final Logger logger = LoggerFactory.getLogger(Measurement.class); - private final Map properties = new TreeMap(); - private long seed; - private int count; - private BBox bbox; - private DistanceCalcEarth distCalc = new DistanceCalcEarth(); - - public static void main(String[] strs) throws Exception { - new Measurement().start(CmdArgs.read(strs)); - } - - // creates measurement result file in the format = - void start(CmdArgs args) throws Exception { - - // read and initialise arguments: - String graphLocation = args.get("graph.location", ""); - String propLocation = args.get("measurement.location", ""); - if (Helper.isEmpty(propLocation)) { - throw new Exception("You must provide an output location via the 'measurement.location' argument"); - } - seed = args.getLong("measurement.seed", 123); - count = args.getInt("measurement.count", 5000); - - // create hopper instance - GraphHopper hopper = new GraphHopperOSM(); - hopper.init(args).forDesktop(); - hopper.getCHFactoryDecorator().setEnabled(true); - hopper.getCHFactoryDecorator().setDisablingAllowed(true); - hopper.importOrLoad(); - String vehicleStr = args.get("graph.flag_encoders", "car"); - FlagEncoder encoder = hopper.getEncodingManager().getEncoder(vehicleStr); - GraphHopperStorage graph = hopper.getGraphHopperStorage(); - bbox = graph.getBounds(); - LocationIndexMatch locationIndex = new LocationIndexMatch(graph, (LocationIndexTree) hopper.getLocationIndex()); - MapMatching mapMatching = new MapMatching(graph, locationIndex, encoder); - - // start tests: - StopWatch sw = new StopWatch().start(); - try { - printLocationIndexMatchQuery(locationIndex); - printTimeOfMapMatchQuery(hopper, mapMatching); - System.gc(); - logger.info("store into " + propLocation); - } catch (Exception ex) { - logger.error("Problem while measuring " + graphLocation, ex); - put("error", ex.toString()); - } finally { - put("measurement.count", count); - put("measurement.seed", seed); - put("measurement.time", sw.stop().getTime()); - System.gc(); - put("measurement.totalMB", Helper.getTotalMB()); - put("measurement.usedMB", Helper.getUsedMB()); - try { - store(new FileWriter(propLocation)); - } catch (IOException ex) { - logger.error("Problem while storing properties " + graphLocation + ", " + propLocation, ex); - } - } - } - - /** - * Test the performance of finding candidate points for the index (which is run for every GPX - * entry). - * - */ - private void printLocationIndexMatchQuery(final LocationIndexMatch idx) { - final double latDelta = bbox.maxLat - bbox.minLat; - final double lonDelta = bbox.maxLon - bbox.minLon; - final Random rand = new Random(seed); - MiniPerfTest miniPerf = new MiniPerfTest() { - @Override - public int doCalc(boolean warmup, int run) { - double lat = rand.nextDouble() * latDelta + bbox.minLat; - double lon = rand.nextDouble() * lonDelta + bbox.minLon; - int val = idx.findNClosest(lat, lon, EdgeFilter.ALL_EDGES, rand.nextDouble() * 500).size(); - return val; - } - }.setIterations(count).start(); - print("location_index_match", miniPerf); - } - - /** - * Test the time taken for map matching on random routes. Note that this includes the index - * lookups (previous tests), so will be affected by those. Otherwise this is largely testing - * the routing and HMM performance. - */ - private void printTimeOfMapMatchQuery(final GraphHopper hopper, final MapMatching mapMatching) { - - // pick random start/end points to create a route, then pick random points from the route, - // and then run the random points through map-matching. - final double latDelta = bbox.maxLat - bbox.minLat; - final double lonDelta = bbox.maxLon - bbox.minLon; - final Random rand = new Random(seed); - mapMatching.setMaxVisitedNodes((int) 1e10); // need to set this high to handle long gaps - MiniPerfTest miniPerf = new MiniPerfTest() { - @Override - public int doCalc(boolean warmup, int run) { - boolean foundPath = false; - - // keep going until we find a path (which we may not for certain start/end points) - while (!foundPath) { - - // create random points and find route between: - double lat0 = bbox.minLat + rand.nextDouble() * latDelta; - double lon0 = bbox.minLon + rand.nextDouble() * lonDelta; - double lat1 = bbox.minLat + rand.nextDouble() * latDelta; - double lon1 = bbox.minLon + rand.nextDouble() * lonDelta; - GHResponse r = hopper.route(new GHRequest(lat0, lon0, lat1, lon1)); - - // if found, use it for map mathching: - if (!r.hasErrors()) { - foundPath = true; - long time = 0; - double sampleProportion = rand.nextDouble(); - GHPoint prev = null; - List mock = new ArrayList(); - PointList points = r.getBest().getPoints(); - // loop through points and add (approximately) sampleProportion of them: - for (GHPoint p : points) { - if (null != prev && rand.nextDouble() < sampleProportion) { - // estimate a reasonable time taken since the last point, so we - // can give the GPXEntry a time. Use the distance between the - // points and a random speed to estimate a time. - double dx = distCalc.calcDist(prev.lat, prev.lon, p.lat, p.lon); - double speedKPH = rand.nextDouble() * 100; - double dt = (dx / 1000) / speedKPH * 3600000; - time += (long) dt; - // randomise the point lat/lon (i.e. so it's not exactly on the route): - GHPoint randomised = distCalc.projectCoordinate(p.lat, p.lat, 20 * rand.nextDouble(), 360 * rand.nextDouble()); - mock.add(new GPXEntry(randomised, time)); - } - } - // now match, provided there are enough points - if (mock.size() > 2) { - mapMatching.doWork(mock); - } else { - foundPath = false; // retry - } - - // TODO: do we need to return something non-trivial? - return 0; - } - } + private static final Logger logger = LoggerFactory.getLogger(Measurement.class); + private final Map properties = new TreeMap(); + private long seed; + private int count; + private BBox bbox; + private DistanceCalcEarth distCalc = new DistanceCalcEarth(); + + public static void main(String[] strs) throws Exception { + new Measurement().start(CmdArgs.read(strs)); + } + + // creates measurement result file in the format = + void start(CmdArgs args) throws Exception { + + // read and initialize arguments: + String graphLocation = args.get("graph.location", ""); + String propLocation = args.get("measurement.location", ""); + if (Helper.isEmpty(propLocation)) { + throw new Exception( + "You must provide an output location via the 'measurement.location' argument"); + } + seed = args.getLong("measurement.seed", 123); + count = args.getInt("measurement.count", 5000); + + // create hopper instance + GraphHopper hopper = new GraphHopperOSM(); + hopper.init(args).forDesktop(); + hopper.getCHFactoryDecorator().setEnabled(true); + hopper.getCHFactoryDecorator().setDisablingAllowed(true); + hopper.importOrLoad(); + String vehicleStr = args.get("graph.flag_encoders", "car"); + FlagEncoder encoder = hopper.getEncodingManager().getEncoder(vehicleStr); + GraphHopperStorage graph = hopper.getGraphHopperStorage(); + bbox = graph.getBounds(); + LocationIndexMatch locationIndex = new LocationIndexMatch(graph, + (LocationIndexTree) hopper.getLocationIndex()); + MapMatching mapMatching = new MapMatching(graph, locationIndex, encoder); + + // start tests: + StopWatch sw = new StopWatch().start(); + try { + printLocationIndexMatchQuery(locationIndex); + printTimeOfMapMatchQuery(hopper, mapMatching); + System.gc(); + logger.info("store into " + propLocation); + } catch (Exception ex) { + logger.error("Problem while measuring " + graphLocation, ex); + put("error", ex.toString()); + } finally { + put("measurement.count", count); + put("measurement.seed", seed); + put("measurement.time", sw.stop().getTime()); + System.gc(); + put("measurement.totalMB", Helper.getTotalMB()); + put("measurement.usedMB", Helper.getUsedMB()); + try { + store(new FileWriter(propLocation)); + } catch (IOException ex) { + logger.error( + "Problem while storing properties " + graphLocation + ", " + propLocation, + ex); + } + } + } + + /** + * Test the performance of finding candidate points for the index (which is run for every GPX + * entry). + * + */ + private void printLocationIndexMatchQuery(final LocationIndexMatch idx) { + final double latDelta = bbox.maxLat - bbox.minLat; + final double lonDelta = bbox.maxLon - bbox.minLon; + final Random rand = new Random(seed); + MiniPerfTest miniPerf = new MiniPerfTest() { + @Override + public int doCalc(boolean warmup, int run) { + double lat = rand.nextDouble() * latDelta + bbox.minLat; + double lon = rand.nextDouble() * lonDelta + bbox.minLon; + int val = idx.findNClosest(lat, lon, EdgeFilter.ALL_EDGES, rand.nextDouble() * 500) + .size(); + return val; + } + }.setIterations(count).start(); + print("location_index_match", miniPerf); + } + + /** + * Test the time taken for map matching on random routes. Note that this includes the index + * lookups (previous tests), so will be affected by those. Otherwise this is largely testing the + * routing and HMM performance. + */ + private void printTimeOfMapMatchQuery(final GraphHopper hopper, final MapMatching mapMatching) { + + // pick random start/end points to create a route, then pick random points from the route, + // and then run the random points through map-matching. + final double latDelta = bbox.maxLat - bbox.minLat; + final double lonDelta = bbox.maxLon - bbox.minLon; + final Random rand = new Random(seed); + mapMatching.setMaxVisitedNodes((int) 1e10); // need to set this high to handle long gaps + MiniPerfTest miniPerf = new MiniPerfTest() { + @Override + public int doCalc(boolean warmup, int run) { + boolean foundPath = false; + + // keep going until we find a path (which we may not for certain start/end points) + while (!foundPath) { + + // create random points and find route between: + double lat0 = bbox.minLat + rand.nextDouble() * latDelta; + double lon0 = bbox.minLon + rand.nextDouble() * lonDelta; + double lat1 = bbox.minLat + rand.nextDouble() * latDelta; + double lon1 = bbox.minLon + rand.nextDouble() * lonDelta; + GHResponse r = hopper.route(new GHRequest(lat0, lon0, lat1, lon1)); + + // if found, use it for map mathching: + if (!r.hasErrors()) { + foundPath = true; + long time = 0; + double sampleProportion = rand.nextDouble(); + GHPoint prev = null; + List mock = new ArrayList(); + PointList points = r.getBest().getPoints(); + // loop through points and add (approximately) sampleProportion of them: + for (GHPoint p : points) { + if (null != prev && rand.nextDouble() < sampleProportion) { + // estimate a reasonable time taken since the last point, so we + // can give the GPXEntry a time. Use the distance between the + // points and a random speed to estimate a time. + double dx = distCalc.calcDist(prev.lat, prev.lon, p.lat, p.lon); + double speedKPH = rand.nextDouble() * 100; + double dt = (dx / 1000) / speedKPH * 3600000; + time += (long) dt; + // randomise the point lat/lon (i.e. so it's not + // exactly on the route): + GHPoint randomised = distCalc.projectCoordinate(p.lat, p.lat, + 20 * rand.nextDouble(), 360 * rand.nextDouble()); + mock.add(new GPXEntry(randomised, time)); + } + } + // now match, provided there are enough points + if (mock.size() > 2) { + mapMatching.doWork(mock); + } else { + foundPath = false; // retry + } + + // TODO: do we need to return something non-trivial? + return 0; + } + } return 0; - } - }.setIterations(count).start(); - print("map_match", miniPerf); - - } - - - void print(String prefix, MiniPerfTest perf) { - logger.info(prefix + ": " + perf.getReport()); - put(prefix + ".sum", perf.getSum()); - put(prefix + ".min", perf.getMin()); - put(prefix + ".mean", perf.getMean()); - put(prefix + ".max", perf.getMax()); - } - - void put(String key, Object val) { - // convert object to string to make serialization possible - properties.put(key, "" + val); - } - - private void store(FileWriter fileWriter) throws IOException { - for (Entry e : properties.entrySet()) { - fileWriter.append(e.getKey()); - fileWriter.append("="); - fileWriter.append(e.getValue()); - fileWriter.append("\n"); - } - fileWriter.flush(); - } + } + }.setIterations(count).start(); + print("map_match", miniPerf); + + } + + void print(String prefix, MiniPerfTest perf) { + logger.info(prefix + ": " + perf.getReport()); + put(prefix + ".sum", perf.getSum()); + put(prefix + ".min", perf.getMin()); + put(prefix + ".mean", perf.getMean()); + put(prefix + ".max", perf.getMax()); + } + + void put(String key, Object val) { + // convert object to string to make serialization possible + properties.put(key, "" + val); + } + + private void store(FileWriter fileWriter) throws IOException { + for (Entry e : properties.entrySet()) { + fileWriter.append(e.getKey()); + fileWriter.append("="); + fileWriter.append(e.getValue()); + fileWriter.append("\n"); + } + fileWriter.flush(); + } } From 48cd988e4fc4d857732a9f7adb612f7980ad7c14 Mon Sep 17 00:00:00 2001 From: kodonnell Date: Thu, 6 Oct 2016 11:37:03 +1300 Subject: [PATCH 08/22] tab to space ... --- .../matching/tools/Measurement.java | 360 +++++++++--------- 1 file changed, 180 insertions(+), 180 deletions(-) diff --git a/matching-tools/src/main/java/com/graphhopper/matching/tools/Measurement.java b/matching-tools/src/main/java/com/graphhopper/matching/tools/Measurement.java index dc9d1bf0..c97f7f76 100644 --- a/matching-tools/src/main/java/com/graphhopper/matching/tools/Measurement.java +++ b/matching-tools/src/main/java/com/graphhopper/matching/tools/Measurement.java @@ -45,184 +45,184 @@ * @author kodonnell */ public class Measurement { - private static final Logger logger = LoggerFactory.getLogger(Measurement.class); - private final Map properties = new TreeMap(); - private long seed; - private int count; - private BBox bbox; - private DistanceCalcEarth distCalc = new DistanceCalcEarth(); - - public static void main(String[] strs) throws Exception { - new Measurement().start(CmdArgs.read(strs)); - } - - // creates measurement result file in the format = - void start(CmdArgs args) throws Exception { - - // read and initialize arguments: - String graphLocation = args.get("graph.location", ""); - String propLocation = args.get("measurement.location", ""); - if (Helper.isEmpty(propLocation)) { - throw new Exception( - "You must provide an output location via the 'measurement.location' argument"); - } - seed = args.getLong("measurement.seed", 123); - count = args.getInt("measurement.count", 5000); - - // create hopper instance - GraphHopper hopper = new GraphHopperOSM(); - hopper.init(args).forDesktop(); - hopper.getCHFactoryDecorator().setEnabled(true); - hopper.getCHFactoryDecorator().setDisablingAllowed(true); - hopper.importOrLoad(); - String vehicleStr = args.get("graph.flag_encoders", "car"); - FlagEncoder encoder = hopper.getEncodingManager().getEncoder(vehicleStr); - GraphHopperStorage graph = hopper.getGraphHopperStorage(); - bbox = graph.getBounds(); - LocationIndexMatch locationIndex = new LocationIndexMatch(graph, - (LocationIndexTree) hopper.getLocationIndex()); - MapMatching mapMatching = new MapMatching(graph, locationIndex, encoder); - - // start tests: - StopWatch sw = new StopWatch().start(); - try { - printLocationIndexMatchQuery(locationIndex); - printTimeOfMapMatchQuery(hopper, mapMatching); - System.gc(); - logger.info("store into " + propLocation); - } catch (Exception ex) { - logger.error("Problem while measuring " + graphLocation, ex); - put("error", ex.toString()); - } finally { - put("measurement.count", count); - put("measurement.seed", seed); - put("measurement.time", sw.stop().getTime()); - System.gc(); - put("measurement.totalMB", Helper.getTotalMB()); - put("measurement.usedMB", Helper.getUsedMB()); - try { - store(new FileWriter(propLocation)); - } catch (IOException ex) { - logger.error( - "Problem while storing properties " + graphLocation + ", " + propLocation, - ex); - } - } - } - - /** - * Test the performance of finding candidate points for the index (which is run for every GPX - * entry). - * - */ - private void printLocationIndexMatchQuery(final LocationIndexMatch idx) { - final double latDelta = bbox.maxLat - bbox.minLat; - final double lonDelta = bbox.maxLon - bbox.minLon; - final Random rand = new Random(seed); - MiniPerfTest miniPerf = new MiniPerfTest() { - @Override - public int doCalc(boolean warmup, int run) { - double lat = rand.nextDouble() * latDelta + bbox.minLat; - double lon = rand.nextDouble() * lonDelta + bbox.minLon; - int val = idx.findNClosest(lat, lon, EdgeFilter.ALL_EDGES, rand.nextDouble() * 500) - .size(); - return val; - } - }.setIterations(count).start(); - print("location_index_match", miniPerf); - } - - /** - * Test the time taken for map matching on random routes. Note that this includes the index - * lookups (previous tests), so will be affected by those. Otherwise this is largely testing the - * routing and HMM performance. - */ - private void printTimeOfMapMatchQuery(final GraphHopper hopper, final MapMatching mapMatching) { - - // pick random start/end points to create a route, then pick random points from the route, - // and then run the random points through map-matching. - final double latDelta = bbox.maxLat - bbox.minLat; - final double lonDelta = bbox.maxLon - bbox.minLon; - final Random rand = new Random(seed); - mapMatching.setMaxVisitedNodes((int) 1e10); // need to set this high to handle long gaps - MiniPerfTest miniPerf = new MiniPerfTest() { - @Override - public int doCalc(boolean warmup, int run) { - boolean foundPath = false; - - // keep going until we find a path (which we may not for certain start/end points) - while (!foundPath) { - - // create random points and find route between: - double lat0 = bbox.minLat + rand.nextDouble() * latDelta; - double lon0 = bbox.minLon + rand.nextDouble() * lonDelta; - double lat1 = bbox.minLat + rand.nextDouble() * latDelta; - double lon1 = bbox.minLon + rand.nextDouble() * lonDelta; - GHResponse r = hopper.route(new GHRequest(lat0, lon0, lat1, lon1)); - - // if found, use it for map mathching: - if (!r.hasErrors()) { - foundPath = true; - long time = 0; - double sampleProportion = rand.nextDouble(); - GHPoint prev = null; - List mock = new ArrayList(); - PointList points = r.getBest().getPoints(); - // loop through points and add (approximately) sampleProportion of them: - for (GHPoint p : points) { - if (null != prev && rand.nextDouble() < sampleProportion) { - // estimate a reasonable time taken since the last point, so we - // can give the GPXEntry a time. Use the distance between the - // points and a random speed to estimate a time. - double dx = distCalc.calcDist(prev.lat, prev.lon, p.lat, p.lon); - double speedKPH = rand.nextDouble() * 100; - double dt = (dx / 1000) / speedKPH * 3600000; - time += (long) dt; - // randomise the point lat/lon (i.e. so it's not - // exactly on the route): - GHPoint randomised = distCalc.projectCoordinate(p.lat, p.lat, - 20 * rand.nextDouble(), 360 * rand.nextDouble()); - mock.add(new GPXEntry(randomised, time)); - } - } - // now match, provided there are enough points - if (mock.size() > 2) { - mapMatching.doWork(mock); - } else { - foundPath = false; // retry - } - - // TODO: do we need to return something non-trivial? - return 0; - } - } - return 0; - } - }.setIterations(count).start(); - print("map_match", miniPerf); - - } - - void print(String prefix, MiniPerfTest perf) { - logger.info(prefix + ": " + perf.getReport()); - put(prefix + ".sum", perf.getSum()); - put(prefix + ".min", perf.getMin()); - put(prefix + ".mean", perf.getMean()); - put(prefix + ".max", perf.getMax()); - } - - void put(String key, Object val) { - // convert object to string to make serialization possible - properties.put(key, "" + val); - } - - private void store(FileWriter fileWriter) throws IOException { - for (Entry e : properties.entrySet()) { - fileWriter.append(e.getKey()); - fileWriter.append("="); - fileWriter.append(e.getValue()); - fileWriter.append("\n"); - } - fileWriter.flush(); - } + private static final Logger logger = LoggerFactory.getLogger(Measurement.class); + private final Map properties = new TreeMap(); + private long seed; + private int count; + private BBox bbox; + private DistanceCalcEarth distCalc = new DistanceCalcEarth(); + + public static void main(String[] strs) throws Exception { + new Measurement().start(CmdArgs.read(strs)); + } + + // creates measurement result file in the format = + void start(CmdArgs args) throws Exception { + + // read and initialize arguments: + String graphLocation = args.get("graph.location", ""); + String propLocation = args.get("measurement.location", ""); + if (Helper.isEmpty(propLocation)) { + throw new Exception( + "You must provide an output location via the 'measurement.location' argument"); + } + seed = args.getLong("measurement.seed", 123); + count = args.getInt("measurement.count", 5000); + + // create hopper instance + GraphHopper hopper = new GraphHopperOSM(); + hopper.init(args).forDesktop(); + hopper.getCHFactoryDecorator().setEnabled(true); + hopper.getCHFactoryDecorator().setDisablingAllowed(true); + hopper.importOrLoad(); + String vehicleStr = args.get("graph.flag_encoders", "car"); + FlagEncoder encoder = hopper.getEncodingManager().getEncoder(vehicleStr); + GraphHopperStorage graph = hopper.getGraphHopperStorage(); + bbox = graph.getBounds(); + LocationIndexMatch locationIndex = new LocationIndexMatch(graph, + (LocationIndexTree) hopper.getLocationIndex()); + MapMatching mapMatching = new MapMatching(graph, locationIndex, encoder); + + // start tests: + StopWatch sw = new StopWatch().start(); + try { + printLocationIndexMatchQuery(locationIndex); + printTimeOfMapMatchQuery(hopper, mapMatching); + System.gc(); + logger.info("store into " + propLocation); + } catch (Exception ex) { + logger.error("Problem while measuring " + graphLocation, ex); + put("error", ex.toString()); + } finally { + put("measurement.count", count); + put("measurement.seed", seed); + put("measurement.time", sw.stop().getTime()); + System.gc(); + put("measurement.totalMB", Helper.getTotalMB()); + put("measurement.usedMB", Helper.getUsedMB()); + try { + store(new FileWriter(propLocation)); + } catch (IOException ex) { + logger.error( + "Problem while storing properties " + graphLocation + ", " + propLocation, + ex); + } + } + } + + /** + * Test the performance of finding candidate points for the index (which is run for every GPX + * entry). + * + */ + private void printLocationIndexMatchQuery(final LocationIndexMatch idx) { + final double latDelta = bbox.maxLat - bbox.minLat; + final double lonDelta = bbox.maxLon - bbox.minLon; + final Random rand = new Random(seed); + MiniPerfTest miniPerf = new MiniPerfTest() { + @Override + public int doCalc(boolean warmup, int run) { + double lat = rand.nextDouble() * latDelta + bbox.minLat; + double lon = rand.nextDouble() * lonDelta + bbox.minLon; + int val = idx.findNClosest(lat, lon, EdgeFilter.ALL_EDGES, rand.nextDouble() * 500) + .size(); + return val; + } + }.setIterations(count).start(); + print("location_index_match", miniPerf); + } + + /** + * Test the time taken for map matching on random routes. Note that this includes the index + * lookups (previous tests), so will be affected by those. Otherwise this is largely testing the + * routing and HMM performance. + */ + private void printTimeOfMapMatchQuery(final GraphHopper hopper, final MapMatching mapMatching) { + + // pick random start/end points to create a route, then pick random points from the route, + // and then run the random points through map-matching. + final double latDelta = bbox.maxLat - bbox.minLat; + final double lonDelta = bbox.maxLon - bbox.minLon; + final Random rand = new Random(seed); + mapMatching.setMaxVisitedNodes((int) 1e10); // need to set this high to handle long gaps + MiniPerfTest miniPerf = new MiniPerfTest() { + @Override + public int doCalc(boolean warmup, int run) { + boolean foundPath = false; + + // keep going until we find a path (which we may not for certain start/end points) + while (!foundPath) { + + // create random points and find route between: + double lat0 = bbox.minLat + rand.nextDouble() * latDelta; + double lon0 = bbox.minLon + rand.nextDouble() * lonDelta; + double lat1 = bbox.minLat + rand.nextDouble() * latDelta; + double lon1 = bbox.minLon + rand.nextDouble() * lonDelta; + GHResponse r = hopper.route(new GHRequest(lat0, lon0, lat1, lon1)); + + // if found, use it for map mathching: + if (!r.hasErrors()) { + foundPath = true; + long time = 0; + double sampleProportion = rand.nextDouble(); + GHPoint prev = null; + List mock = new ArrayList(); + PointList points = r.getBest().getPoints(); + // loop through points and add (approximately) sampleProportion of them: + for (GHPoint p : points) { + if (null != prev && rand.nextDouble() < sampleProportion) { + // estimate a reasonable time taken since the last point, so we + // can give the GPXEntry a time. Use the distance between the + // points and a random speed to estimate a time. + double dx = distCalc.calcDist(prev.lat, prev.lon, p.lat, p.lon); + double speedKPH = rand.nextDouble() * 100; + double dt = (dx / 1000) / speedKPH * 3600000; + time += (long) dt; + // randomise the point lat/lon (i.e. so it's not + // exactly on the route): + GHPoint randomised = distCalc.projectCoordinate(p.lat, p.lat, + 20 * rand.nextDouble(), 360 * rand.nextDouble()); + mock.add(new GPXEntry(randomised, time)); + } + } + // now match, provided there are enough points + if (mock.size() > 2) { + mapMatching.doWork(mock); + } else { + foundPath = false; // retry + } + + // TODO: do we need to return something non-trivial? + return 0; + } + } + return 0; + } + }.setIterations(count).start(); + print("map_match", miniPerf); + + } + + void print(String prefix, MiniPerfTest perf) { + logger.info(prefix + ": " + perf.getReport()); + put(prefix + ".sum", perf.getSum()); + put(prefix + ".min", perf.getMin()); + put(prefix + ".mean", perf.getMean()); + put(prefix + ".max", perf.getMax()); + } + + void put(String key, Object val) { + // convert object to string to make serialization possible + properties.put(key, "" + val); + } + + private void store(FileWriter fileWriter) throws IOException { + for (Entry e : properties.entrySet()) { + fileWriter.append(e.getKey()); + fileWriter.append("="); + fileWriter.append(e.getValue()); + fileWriter.append("\n"); + } + fileWriter.flush(); + } } From 696820c011090113c5ed56b4e223179626166752 Mon Sep 17 00:00:00 2001 From: kodonnell Date: Sun, 16 Oct 2016 08:29:53 +1300 Subject: [PATCH 09/22] updated to new API change, plus fixed test bug --- .../matching/tools/Measurement.java | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/matching-tools/src/main/java/com/graphhopper/matching/tools/Measurement.java b/matching-tools/src/main/java/com/graphhopper/matching/tools/Measurement.java index c97f7f76..245fdfaf 100644 --- a/matching-tools/src/main/java/com/graphhopper/matching/tools/Measurement.java +++ b/matching-tools/src/main/java/com/graphhopper/matching/tools/Measurement.java @@ -22,7 +22,9 @@ import com.graphhopper.GraphHopper; import com.graphhopper.matching.LocationIndexMatch; import com.graphhopper.matching.MapMatching; +import com.graphhopper.matching.MatchResult; import com.graphhopper.reader.osm.GraphHopperOSM; +import com.graphhopper.routing.AlgorithmOptions; import com.graphhopper.routing.util.*; import com.graphhopper.storage.GraphHopperStorage; import com.graphhopper.storage.index.LocationIndexTree; @@ -75,14 +77,18 @@ void start(CmdArgs args) throws Exception { hopper.getCHFactoryDecorator().setEnabled(true); hopper.getCHFactoryDecorator().setDisablingAllowed(true); hopper.importOrLoad(); - String vehicleStr = args.get("graph.flag_encoders", "car"); - FlagEncoder encoder = hopper.getEncodingManager().getEncoder(vehicleStr); + + // and map-matching stuff GraphHopperStorage graph = hopper.getGraphHopperStorage(); bbox = graph.getBounds(); LocationIndexMatch locationIndex = new LocationIndexMatch(graph, (LocationIndexTree) hopper.getLocationIndex()); - MapMatching mapMatching = new MapMatching(graph, locationIndex, encoder); - + // TODO: allow tests of non-CH? + AlgorithmOptions algoOpts = AlgorithmOptions.start() + .maxVisitedNodes((int) 1e10) + .build(); + MapMatching mapMatching = new MapMatching(hopper, algoOpts); + // start tests: StopWatch sw = new StopWatch().start(); try { @@ -144,7 +150,6 @@ private void printTimeOfMapMatchQuery(final GraphHopper hopper, final MapMatchin final double latDelta = bbox.maxLat - bbox.minLat; final double lonDelta = bbox.maxLon - bbox.minLon; final Random rand = new Random(seed); - mapMatching.setMaxVisitedNodes((int) 1e10); // need to set this high to handle long gaps MiniPerfTest miniPerf = new MiniPerfTest() { @Override public int doCalc(boolean warmup, int run) { @@ -187,13 +192,12 @@ public int doCalc(boolean warmup, int run) { } // now match, provided there are enough points if (mock.size() > 2) { - mapMatching.doWork(mock); + MatchResult match = mapMatching.doWork(mock); + // return something non-trivial, to avoid JVM optimizing away + return match.getEdgeMatches().size(); } else { foundPath = false; // retry } - - // TODO: do we need to return something non-trivial? - return 0; } } return 0; From 3f3829a5afbe1a6144b241a3a315de3a750ae9cf Mon Sep 17 00:00:00 2001 From: kodonnell Date: Sun, 16 Oct 2016 08:34:22 +1300 Subject: [PATCH 10/22] fixed infinite loop --- .../main/java/com/graphhopper/matching/tools/Measurement.java | 1 + 1 file changed, 1 insertion(+) diff --git a/matching-tools/src/main/java/com/graphhopper/matching/tools/Measurement.java b/matching-tools/src/main/java/com/graphhopper/matching/tools/Measurement.java index 245fdfaf..74bfd3b5 100644 --- a/matching-tools/src/main/java/com/graphhopper/matching/tools/Measurement.java +++ b/matching-tools/src/main/java/com/graphhopper/matching/tools/Measurement.java @@ -189,6 +189,7 @@ public int doCalc(boolean warmup, int run) { 20 * rand.nextDouble(), 360 * rand.nextDouble()); mock.add(new GPXEntry(randomised, time)); } + prev = p; } // now match, provided there are enough points if (mock.size() > 2) { From d540a14cfd5901b40eb22a1fe27dbf2aa4756cd0 Mon Sep 17 00:00:00 2001 From: kodonnell Date: Sun, 16 Oct 2016 09:39:32 +1300 Subject: [PATCH 11/22] OK, perf tests working correctly ... hopefully --- map-matching.sh | 6 ++---- .../graphhopper/matching/tools/Measurement.java | 15 ++++++++++----- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/map-matching.sh b/map-matching.sh index 8e162e6b..de9188cf 100755 --- a/map-matching.sh +++ b/map-matching.sh @@ -38,8 +38,8 @@ elif [ "$1" = "action=measurement" ]; then current_commit=$(git log -n 1 --pretty=oneline | cut -d' ' -f1) function startMeasurement { echo -e "\nperforming measurement for commit $current_commit" - echo $measurement_fname - echo "$JAVA" $JAVA_OPTS -cp "$JAR" com.graphhopper.matching.tools.Measurement $ARGS measurement.location="$measurement_fname" + mvn --projects matching-tools -DskipTests=true clean install assembly:single + rm -f "$measurement_fname" "$JAVA" $JAVA_OPTS -cp "$JAR" com.graphhopper.matching.tools.Measurement $ARGS measurement.location="$measurement_fname" } @@ -61,8 +61,6 @@ elif [ "$1" = "action=measurement" ]; then for commit in $commits; do git checkout "$commit" git log -n 1 --pretty=oneline >> "$fname" - mvn --projects matching-tools -DskipTests=true clean install assembly:single - rm -f "$measurement_fname" startMeasurement while read -r line; do key=${line%%=*} diff --git a/matching-tools/src/main/java/com/graphhopper/matching/tools/Measurement.java b/matching-tools/src/main/java/com/graphhopper/matching/tools/Measurement.java index 74bfd3b5..98780fab 100644 --- a/matching-tools/src/main/java/com/graphhopper/matching/tools/Measurement.java +++ b/matching-tools/src/main/java/com/graphhopper/matching/tools/Measurement.java @@ -85,7 +85,7 @@ void start(CmdArgs args) throws Exception { (LocationIndexTree) hopper.getLocationIndex()); // TODO: allow tests of non-CH? AlgorithmOptions algoOpts = AlgorithmOptions.start() - .maxVisitedNodes((int) 1e10) + .maxVisitedNodes((int) 1e20) .build(); MapMatching mapMatching = new MapMatching(hopper, algoOpts); @@ -150,6 +150,12 @@ private void printTimeOfMapMatchQuery(final GraphHopper hopper, final MapMatchin final double latDelta = bbox.maxLat - bbox.minLat; final double lonDelta = bbox.maxLon - bbox.minLon; final Random rand = new Random(seed); + // this takes a while, so we'll limit it to 100 tests: + int n = count; + if (n > 100) { + logger.warn("map matching query tests take a while, so we'll only do 100 iterations (instead of " + count + ")"); + n = 100; + } MiniPerfTest miniPerf = new MiniPerfTest() { @Override public int doCalc(boolean warmup, int run) { @@ -185,7 +191,7 @@ public int doCalc(boolean warmup, int run) { time += (long) dt; // randomise the point lat/lon (i.e. so it's not // exactly on the route): - GHPoint randomised = distCalc.projectCoordinate(p.lat, p.lat, + GHPoint randomised = distCalc.projectCoordinate(p.lat, p.lon, 20 * rand.nextDouble(), 360 * rand.nextDouble()); mock.add(new GPXEntry(randomised, time)); } @@ -203,14 +209,13 @@ public int doCalc(boolean warmup, int run) { } return 0; } - }.setIterations(count).start(); + }.setIterations(n).start(); print("map_match", miniPerf); - } void print(String prefix, MiniPerfTest perf) { logger.info(prefix + ": " + perf.getReport()); - put(prefix + ".sum", perf.getSum()); + put(prefix + ".sum", perf.getSum()); put(prefix + ".min", perf.getMin()); put(prefix + ".mean", perf.getMean()); put(prefix + ".max", perf.getMax()); From 7cb64783b498531e88d53029c01b03d642fbedd7 Mon Sep 17 00:00:00 2001 From: kodonnell Date: Sun, 4 Dec 2016 15:33:59 +1300 Subject: [PATCH 12/22] removed separate tools module and set name same as GH --- map-matching.sh | 36 +++++++-------- .../matching/util}/Measurement.java | 2 +- matching-tools/pom.xml | 46 ------------------- pom.xml | 1 - 4 files changed, 19 insertions(+), 66 deletions(-) rename {matching-tools/src/main/java/com/graphhopper/matching/tools => matching-core/src/main/java/com/graphhopper/matching/util}/Measurement.java (99%) delete mode 100644 matching-tools/pom.xml diff --git a/map-matching.sh b/map-matching.sh index de9188cf..6453f8c3 100755 --- a/map-matching.sh +++ b/map-matching.sh @@ -32,63 +32,63 @@ elif [ "$1" = "action=test" ]; then # return exit code of mvn exit $? elif [ "$1" = "action=measurement" ]; then - set_jar "tools" - fname="measurement.$(date +%Y%m%d_%H%M%S)" + set_jar "core" ARGS="config=$CONFIG graph.location=$GRAPH datareader.file=$2 prepare.ch.weightings=fastest graph.flag_encoders=car prepare.min_network_size=10000 prepare.min_oneway_network_size=10000" current_commit=$(git log -n 1 --pretty=oneline | cut -d' ' -f1) function startMeasurement { echo -e "\nperforming measurement for commit $current_commit" - mvn --projects matching-tools -DskipTests=true clean install assembly:single - rm -f "$measurement_fname" - "$JAVA" $JAVA_OPTS -cp "$JAR" com.graphhopper.matching.tools.Measurement $ARGS measurement.location="$measurement_fname" + mvn --projects matching-core -DskipTests=true clean install assembly:single + measurement_fname="measurement$(date +%Y-%m-%d_%H_%M_%S).properties" + "$JAVA" $JAVA_OPTS -cp "$JAR" com.graphhopper.matching.util.Measurement $ARGS measurement.location="$measurement_fname" } # use all versions starting from HEAD last_commits=$3 if [ -z "$last_commits" ]; then - measurement_fname=$fname startMeasurement else # the following checks out the last commits, and tests each one. The code looks a bit # messier than that, as we merge the results into a single file (to make it easier to # compare. - echo -e "commits (in order tested):\n--------------------------\n" >> "$fname" - values=${fname}.values - measurement_fname=${fname}.tmp + combined="measurement_$(git rev-list HEAD -n $last_commits | tail -n1)_$(git rev-list HEAD -n 1 | head -n1)" + tmp_values="$combined.values" + echo -e "commits (in order tested):\n--------------------------\n" > "$combined" commits=$(git rev-list HEAD -n "$last_commits") first=true empty_pad="" for commit in $commits; do git checkout "$commit" - git log -n 1 --pretty=oneline >> "$fname" + git log -n 1 --pretty=oneline >> "$combined" + # do measurement for this commit startMeasurement + # now merge it: while read -r line; do key=${line%%=*} value=$(printf "%-20s" "${line##*=}") if [ "$first" = true ] ; then - printf "%-30s%s\n" "$key" "$value" >> "$values" + printf "%-30s%s\n" "$key" "$value" >> "$tmp_values" else if grep "$key" "$values"; then - sed -ri "s/($key.*)/\1$value/g" "$values" + sed -ri "s/($key.*)/\1$value/g" "$tmp_values" else # add a new row, using $empty_pad to get the column in the right place - printf "%-30s%s%s\n" "$key" "$empty_pad" "$value" >> "$values" + printf "%-30s%s%s\n" "$key" "$empty_pad" "$value" >> "$tmp_values" fi fi done < "$measurement_fname" first=false empty_pad=$(printf "%s%-20s" "$empty_pad" "") done - echo -e "\nmeasurements:\n-------------\n" >> "$fname" - cat "$values" >> "$fname" - rm "$values" - rm "$measurement_fname" + echo -e "\nmeasurements:\n-------------\n" >> "$combined" + cat "$tmp_values" >> "$combined" + # tidy up + rm "$tmp_values" # revert checkout git checkout "$current_commit" fi # in either case, echo the file: echo "" - cat "$fname" + cat "$measurement_fname" exit 0 else set_jar "core" diff --git a/matching-tools/src/main/java/com/graphhopper/matching/tools/Measurement.java b/matching-core/src/main/java/com/graphhopper/matching/util/Measurement.java similarity index 99% rename from matching-tools/src/main/java/com/graphhopper/matching/tools/Measurement.java rename to matching-core/src/main/java/com/graphhopper/matching/util/Measurement.java index 98780fab..fbf1505f 100644 --- a/matching-tools/src/main/java/com/graphhopper/matching/tools/Measurement.java +++ b/matching-core/src/main/java/com/graphhopper/matching/util/Measurement.java @@ -15,7 +15,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.graphhopper.matching.tools; +package com.graphhopper.matching.util; import com.graphhopper.GHRequest; import com.graphhopper.GHResponse; diff --git a/matching-tools/pom.xml b/matching-tools/pom.xml deleted file mode 100644 index 072a8c45..00000000 --- a/matching-tools/pom.xml +++ /dev/null @@ -1,46 +0,0 @@ - - 4.0.0 - GraphHopper Map Matching Tools - com.graphhopper - graphhopper-map-matching-tools - 0.8-SNAPSHOT - - com.graphhopper - graphhopper-map-matching-parent - 0.8-SNAPSHOT - - - - com.graphhopper - graphhopper-map-matching-core - ${project.parent.version} - - - - - - maven-compiler-plugin - 3.5.1 - - 1.8 - 1.8 - - - - org.apache.maven.plugins - maven-assembly-plugin - - - - com.graphhopper.matching.tools.Measurement - - - - jar-with-dependencies - - - - - - \ No newline at end of file diff --git a/pom.xml b/pom.xml index 424dd657..c40dda07 100644 --- a/pom.xml +++ b/pom.xml @@ -74,7 +74,6 @@ hmm-lib matching-core matching-web - matching-tools From 7bb0ad86f606ab27c0326ce3c0f061127d07704c Mon Sep 17 00:00:00 2001 From: kodonnell Date: Sun, 4 Dec 2016 15:45:51 +1300 Subject: [PATCH 13/22] tidy file name and bug fix --- map-matching.sh | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/map-matching.sh b/map-matching.sh index 6453f8c3..61a11f29 100755 --- a/map-matching.sh +++ b/map-matching.sh @@ -46,11 +46,14 @@ elif [ "$1" = "action=measurement" ]; then last_commits=$3 if [ -z "$last_commits" ]; then startMeasurement + echo "" + cat "$measurement_fname" + exit 0 else # the following checks out the last commits, and tests each one. The code looks a bit # messier than that, as we merge the results into a single file (to make it easier to # compare. - combined="measurement_$(git rev-list HEAD -n $last_commits | tail -n1)_$(git rev-list HEAD -n 1 | head -n1)" + combined="measurement_$(git log --format="%h" | head -n $last_commits | tail -n1)_$(git log --format="%h" | head -n1)" tmp_values="$combined.values" echo -e "commits (in order tested):\n--------------------------\n" > "$combined" commits=$(git rev-list HEAD -n "$last_commits") @@ -68,7 +71,7 @@ elif [ "$1" = "action=measurement" ]; then if [ "$first" = true ] ; then printf "%-30s%s\n" "$key" "$value" >> "$tmp_values" else - if grep "$key" "$values"; then + if grep "$key" "$tmp_values"; then sed -ri "s/($key.*)/\1$value/g" "$tmp_values" else # add a new row, using $empty_pad to get the column in the right place @@ -85,11 +88,11 @@ elif [ "$1" = "action=measurement" ]; then rm "$tmp_values" # revert checkout git checkout "$current_commit" + # done: + echo "" + cat "$combined" + exit 0 fi - # in either case, echo the file: - echo "" - cat "$measurement_fname" - exit 0 else set_jar "core" ARGS="$@" From 1b28b042fdba9174518246d806068e3653141442 Mon Sep 17 00:00:00 2001 From: kodonnell Date: Sun, 4 Dec 2016 16:19:02 +1300 Subject: [PATCH 14/22] commit header for each col --- map-matching.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/map-matching.sh b/map-matching.sh index 61a11f29..ffa02165 100755 --- a/map-matching.sh +++ b/map-matching.sh @@ -59,11 +59,16 @@ elif [ "$1" = "action=measurement" ]; then commits=$(git rev-list HEAD -n "$last_commits") first=true empty_pad="" + header=$(printf "%30s" "") + subheader=$header for commit in $commits; do git checkout "$commit" git log -n 1 --pretty=oneline >> "$combined" # do measurement for this commit startMeasurement + # update headers: + header=$(printf "%s%-20s" "$header" $(echo "$commit" | cut -c1-7)) + subheader=$(printf "%s%-20s" "$subheader" "-------") # now merge it: while read -r line; do key=${line%%=*} @@ -83,6 +88,8 @@ elif [ "$1" = "action=measurement" ]; then empty_pad=$(printf "%s%-20s" "$empty_pad" "") done echo -e "\nmeasurements:\n-------------\n" >> "$combined" + echo "$header" >> "$combined" + echo "$subheader" >> "$combined" cat "$tmp_values" >> "$combined" # tidy up rm "$tmp_values" From f83558d9d46eb6a2011bc56b03c7be36bc45b12f Mon Sep 17 00:00:00 2001 From: kodonnell Date: Sun, 4 Dec 2016 16:24:41 +1300 Subject: [PATCH 15/22] start with oldest commit first --- map-matching.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/map-matching.sh b/map-matching.sh index ffa02165..0820dac4 100755 --- a/map-matching.sh +++ b/map-matching.sh @@ -56,7 +56,7 @@ elif [ "$1" = "action=measurement" ]; then combined="measurement_$(git log --format="%h" | head -n $last_commits | tail -n1)_$(git log --format="%h" | head -n1)" tmp_values="$combined.values" echo -e "commits (in order tested):\n--------------------------\n" > "$combined" - commits=$(git rev-list HEAD -n "$last_commits") + commits=$(git rev-list HEAD -n "$last_commits" | tac) # NOTE: tac is to reverse so we start with oldest first first=true empty_pad="" header=$(printf "%30s" "") From 173bed8eac9807b14f1802897e01f2c6286aa55f Mon Sep 17 00:00:00 2001 From: kodonnell Date: Sun, 4 Dec 2016 16:59:24 +1300 Subject: [PATCH 16/22] playing with graphs --- map-matching.sh | 49 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/map-matching.sh b/map-matching.sh index 0820dac4..b5143511 100755 --- a/map-matching.sh +++ b/map-matching.sh @@ -53,8 +53,9 @@ elif [ "$1" = "action=measurement" ]; then # the following checks out the last commits, and tests each one. The code looks a bit # messier than that, as we merge the results into a single file (to make it easier to # compare. - combined="measurement_$(git log --format="%h" | head -n $last_commits | tail -n1)_$(git log --format="%h" | head -n1)" + combined="measurement_$(git log --format="%h" | head -n $last_commits | tail -n1)_$(git log --format="%h" | head -n1).properties" tmp_values="$combined.values" + rm -f "$tmp_values" echo -e "commits (in order tested):\n--------------------------\n" > "$combined" commits=$(git rev-list HEAD -n "$last_commits" | tac) # NOTE: tac is to reverse so we start with oldest first first=true @@ -76,7 +77,7 @@ elif [ "$1" = "action=measurement" ]; then if [ "$first" = true ] ; then printf "%-30s%s\n" "$key" "$value" >> "$tmp_values" else - if grep "$key" "$tmp_values"; then + if grep "$key" "$tmp_values" > /dev/null; then sed -ri "s/($key.*)/\1$value/g" "$tmp_values" else # add a new row, using $empty_pad to get the column in the right place @@ -91,13 +92,53 @@ elif [ "$1" = "action=measurement" ]; then echo "$header" >> "$combined" echo "$subheader" >> "$combined" cat "$tmp_values" >> "$combined" + + # now plot (if supported) + plot=1 + if ! type "bc" > /dev/null; then + echo "install `bc` if you want plots" + plot=0 + fi + if ! type "gnuplot" > /dev/null; then + echo "install `gnuplot` if you want plots" + plot=0 + fi + if [ $last_commits -lt 2 ]; then + echo "plots are only performed if you specify a history of more than one commit" + plot=0 + fi + + if [ $plot -eq 1 ]; then + while read -r line; do + data= + i=0 + title=$(echo $line | cut -d" " -f1) + mx= + for commit in $commits; do + val=$(echo $line | cut -d" " -f"$((i+2))") + [[ ( $i -eq 0 || $(echo "$val > $mx" | bc) -eq 1 ) ]] && mx=$val + data="$data$i\t$(echo $commit | cut -c1-7)\t$val\n" + i=$((i + 1)) + done + if [ $(echo "$mx > 0" | bc) -eq 1 ]; then + mn=0 + else + mn=$mx + mx=0 + fi + echo -e "$data" | gnuplot -e "set terminal dumb; set yrange [$mn:$mx]; set boxwidth 0.5; set style fill solid; set border 1; unset tics; set xtics border; unset key; set title '$title'; plot '> "$combined" + done < "$tmp_values" + fi + + # display it: + echo "" + cat "$combined" + # tidy up rm "$tmp_values" # revert checkout git checkout "$current_commit" # done: - echo "" - cat "$combined" exit 0 fi else From 544163986a9e30864aa58c41c2042986d0fd6c66 Mon Sep 17 00:00:00 2001 From: kodonnell Date: Sun, 4 Dec 2016 18:17:34 +1300 Subject: [PATCH 17/22] show charts one by one --- map-matching.sh | 66 ++++++++++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 28 deletions(-) diff --git a/map-matching.sh b/map-matching.sh index b5143511..97d75cfa 100755 --- a/map-matching.sh +++ b/map-matching.sh @@ -34,7 +34,7 @@ elif [ "$1" = "action=test" ]; then elif [ "$1" = "action=measurement" ]; then set_jar "core" ARGS="config=$CONFIG graph.location=$GRAPH datareader.file=$2 prepare.ch.weightings=fastest graph.flag_encoders=car prepare.min_network_size=10000 prepare.min_oneway_network_size=10000" - current_commit=$(git log -n 1 --pretty=oneline | cut -d' ' -f1) + current_branch=$(git rev-parse --abbrev-ref HEAD) function startMeasurement { echo -e "\nperforming measurement for commit $current_commit" mvn --projects matching-core -DskipTests=true clean install assembly:single @@ -92,6 +92,11 @@ elif [ "$1" = "action=measurement" ]; then echo "$header" >> "$combined" echo "$subheader" >> "$combined" cat "$tmp_values" >> "$combined" + echo "" >> "$combined" + + # show as is: + echo "" + cat "$combined" # now plot (if supported) plot=1 @@ -108,36 +113,41 @@ elif [ "$1" = "action=measurement" ]; then plot=0 fi + # remove tmp file when done + trap "rm '$tmp_values'; git checkout $current_branch" EXIT INT TERM + + # plot all to file first, then plot again for interactivity: if [ $plot -eq 1 ]; then - while read -r line; do - data= - i=0 - title=$(echo $line | cut -d" " -f1) - mx= - for commit in $commits; do - val=$(echo $line | cut -d" " -f"$((i+2))") - [[ ( $i -eq 0 || $(echo "$val > $mx" | bc) -eq 1 ) ]] && mx=$val - data="$data$i\t$(echo $commit | cut -c1-7)\t$val\n" - i=$((i + 1)) - done - if [ $(echo "$mx > 0" | bc) -eq 1 ]; then - mn=0 - else - mn=$mx - mx=0 - fi - echo -e "$data" | gnuplot -e "set terminal dumb; set yrange [$mn:$mx]; set boxwidth 0.5; set style fill solid; set border 1; unset tics; set xtics border; unset key; set title '$title'; plot '> "$combined" - done < "$tmp_values" + for first in {0..1}; do + while read -u 3 -r line; do + data= + i=0 + title=$(echo $line | cut -d" " -f1) + mx= + for commit in $commits; do + val=$(echo $line | cut -d" " -f"$((i+2))") + [[ ( $i -eq 0 || $(echo "$val > $mx" | bc) -eq 1 ) ]] && mx=$val + data="$data$i\t$(echo $commit | cut -c1-7)\t$val\n" + i=$((i + 1)) + done + if [ $(echo "$mx > 0" | bc) -eq 1 ]; then + mn=0 + else + mn=$mx + mx=0 + fi + chart=$(echo -e "$data" | gnuplot -e "set terminal dumb; set yrange [$mn:$mx]; set boxwidth 0.5; set style fill solid; set border 1; unset tics; set xtics border; unset key; set title '$title'; plot '> "$combined" + else + echo "" + echo -e "$chart" + read -rsp $'Press any key to view the next chart, or CTRL + C to exit ...\n' -n1 key + fi + done 3< "$tmp_values" + done fi - # display it: - echo "" - cat "$combined" - - # tidy up - rm "$tmp_values" - # revert checkout - git checkout "$current_commit" # done: exit 0 fi From 2a990e1d115192c8f8f1ab74a1b62ec4c077c1d6 Mon Sep 17 00:00:00 2001 From: kodonnell Date: Sun, 4 Dec 2016 18:17:34 +1300 Subject: [PATCH 18/22] show charts one by one --- map-matching.sh | 70 ++++++++++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 30 deletions(-) diff --git a/map-matching.sh b/map-matching.sh index b5143511..3f164fdb 100755 --- a/map-matching.sh +++ b/map-matching.sh @@ -34,7 +34,7 @@ elif [ "$1" = "action=test" ]; then elif [ "$1" = "action=measurement" ]; then set_jar "core" ARGS="config=$CONFIG graph.location=$GRAPH datareader.file=$2 prepare.ch.weightings=fastest graph.flag_encoders=car prepare.min_network_size=10000 prepare.min_oneway_network_size=10000" - current_commit=$(git log -n 1 --pretty=oneline | cut -d' ' -f1) + current_branch=$(git rev-parse --abbrev-ref HEAD) function startMeasurement { echo -e "\nperforming measurement for commit $current_commit" mvn --projects matching-core -DskipTests=true clean install assembly:single @@ -56,7 +56,7 @@ elif [ "$1" = "action=measurement" ]; then combined="measurement_$(git log --format="%h" | head -n $last_commits | tail -n1)_$(git log --format="%h" | head -n1).properties" tmp_values="$combined.values" rm -f "$tmp_values" - echo -e "commits (in order tested):\n--------------------------\n" > "$combined" + echo -e "commits:\n--------------------------\n" > "$combined" commits=$(git rev-list HEAD -n "$last_commits" | tac) # NOTE: tac is to reverse so we start with oldest first first=true empty_pad="" @@ -64,7 +64,7 @@ elif [ "$1" = "action=measurement" ]; then subheader=$header for commit in $commits; do git checkout "$commit" - git log -n 1 --pretty=oneline >> "$combined" + git log --format="%h [%cd] %s" --date=short -n 1 >> "$combined" # do measurement for this commit startMeasurement # update headers: @@ -92,6 +92,11 @@ elif [ "$1" = "action=measurement" ]; then echo "$header" >> "$combined" echo "$subheader" >> "$combined" cat "$tmp_values" >> "$combined" + echo "" >> "$combined" + + # show as is: + echo "" + cat "$combined" # now plot (if supported) plot=1 @@ -108,36 +113,41 @@ elif [ "$1" = "action=measurement" ]; then plot=0 fi + # remove tmp file when done + trap "rm '$tmp_values'; git checkout $current_branch" EXIT INT TERM + + # plot all to file first, then plot again for interactivity: if [ $plot -eq 1 ]; then - while read -r line; do - data= - i=0 - title=$(echo $line | cut -d" " -f1) - mx= - for commit in $commits; do - val=$(echo $line | cut -d" " -f"$((i+2))") - [[ ( $i -eq 0 || $(echo "$val > $mx" | bc) -eq 1 ) ]] && mx=$val - data="$data$i\t$(echo $commit | cut -c1-7)\t$val\n" - i=$((i + 1)) - done - if [ $(echo "$mx > 0" | bc) -eq 1 ]; then - mn=0 - else - mn=$mx - mx=0 - fi - echo -e "$data" | gnuplot -e "set terminal dumb; set yrange [$mn:$mx]; set boxwidth 0.5; set style fill solid; set border 1; unset tics; set xtics border; unset key; set title '$title'; plot '> "$combined" - done < "$tmp_values" + for first in {0..1}; do + while read -u 3 -r line; do + data= + i=0 + title=$(echo $line | cut -d" " -f1) + mx= + for commit in $commits; do + val=$(echo $line | cut -d" " -f"$((i+2))") + [[ ( $i -eq 0 || $(echo "$val > $mx" | bc) -eq 1 ) ]] && mx=$val + data="$data$i\t$(echo $commit | cut -c1-7)\t$val\n" + i=$((i + 1)) + done + if [ $(echo "$mx > 0" | bc) -eq 1 ]; then + mn=0 + else + mn=$mx + mx=0 + fi + chart=$(echo -e "$data" | gnuplot -e "set terminal dumb; set yrange [$mn:$mx]; set boxwidth 0.5; set style fill solid; set border 1; unset tics; set xtics border; unset key; set title '$title'; plot '> "$combined" + else + echo "" + echo -e "$chart" + read -rsp $'Press any key to view the next chart, or CTRL + C to exit ...\n' -n1 key + fi + done 3< "$tmp_values" + done fi - # display it: - echo "" - cat "$combined" - - # tidy up - rm "$tmp_values" - # revert checkout - git checkout "$current_commit" # done: exit 0 fi From c38265d121e7543a61f4e5668be8e41eee9939de Mon Sep 17 00:00:00 2001 From: kodonnell Date: Sun, 4 Dec 2016 19:15:47 +1300 Subject: [PATCH 19/22] woops, fixing trap --- map-matching.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/map-matching.sh b/map-matching.sh index 3f164fdb..a8e43bba 100755 --- a/map-matching.sh +++ b/map-matching.sh @@ -113,8 +113,8 @@ elif [ "$1" = "action=measurement" ]; then plot=0 fi - # remove tmp file when done - trap "rm '$tmp_values'; git checkout $current_branch" EXIT INT TERM + # remove tmp file and change back to original branch when done: + trap "rm -f '$tmp_values'; git checkout $current_branch" EXIT # plot all to file first, then plot again for interactivity: if [ $plot -eq 1 ]; then From 38790e46e1cc88c2e0c6c81881a660f1fcc6a4eb Mon Sep 17 00:00:00 2001 From: kodonnell Date: Sun, 4 Dec 2016 20:56:36 +1300 Subject: [PATCH 20/22] clear charts --- map-matching.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/map-matching.sh b/map-matching.sh index a8e43bba..8acdc7e6 100755 --- a/map-matching.sh +++ b/map-matching.sh @@ -119,6 +119,7 @@ elif [ "$1" = "action=measurement" ]; then # plot all to file first, then plot again for interactivity: if [ $plot -eq 1 ]; then for first in {0..1}; do + num_lines_last_chart=0 while read -u 3 -r line; do data= i=0 @@ -140,7 +141,10 @@ elif [ "$1" = "action=measurement" ]; then if [ $first -eq 0 ]; then echo -e "$chart" >> "$combined" else - echo "" + # clear old one: + printf "%0.s\033[1A\033[K" $(seq 0 $((num_lines_last_chart + 1))) + num_lines_last_chart=$(echo -e "$chart" | wc -l) + # show this one: echo -e "$chart" read -rsp $'Press any key to view the next chart, or CTRL + C to exit ...\n' -n1 key fi From 028add73bff1425efdda8b0937a2f2109d6e1697 Mon Sep 17 00:00:00 2001 From: kodonnell Date: Wed, 7 Dec 2016 07:21:42 +1300 Subject: [PATCH 21/22] removing gnuplots --- map-matching.sh | 59 +++---------------------------------------------- 1 file changed, 3 insertions(+), 56 deletions(-) diff --git a/map-matching.sh b/map-matching.sh index 8acdc7e6..9f5cd019 100755 --- a/map-matching.sh +++ b/map-matching.sh @@ -92,67 +92,14 @@ elif [ "$1" = "action=measurement" ]; then echo "$header" >> "$combined" echo "$subheader" >> "$combined" cat "$tmp_values" >> "$combined" - echo "" >> "$combined" # show as is: echo "" cat "$combined" - # now plot (if supported) - plot=1 - if ! type "bc" > /dev/null; then - echo "install `bc` if you want plots" - plot=0 - fi - if ! type "gnuplot" > /dev/null; then - echo "install `gnuplot` if you want plots" - plot=0 - fi - if [ $last_commits -lt 2 ]; then - echo "plots are only performed if you specify a history of more than one commit" - plot=0 - fi - - # remove tmp file and change back to original branch when done: - trap "rm -f '$tmp_values'; git checkout $current_branch" EXIT - - # plot all to file first, then plot again for interactivity: - if [ $plot -eq 1 ]; then - for first in {0..1}; do - num_lines_last_chart=0 - while read -u 3 -r line; do - data= - i=0 - title=$(echo $line | cut -d" " -f1) - mx= - for commit in $commits; do - val=$(echo $line | cut -d" " -f"$((i+2))") - [[ ( $i -eq 0 || $(echo "$val > $mx" | bc) -eq 1 ) ]] && mx=$val - data="$data$i\t$(echo $commit | cut -c1-7)\t$val\n" - i=$((i + 1)) - done - if [ $(echo "$mx > 0" | bc) -eq 1 ]; then - mn=0 - else - mn=$mx - mx=0 - fi - chart=$(echo -e "$data" | gnuplot -e "set terminal dumb; set yrange [$mn:$mx]; set boxwidth 0.5; set style fill solid; set border 1; unset tics; set xtics border; unset key; set title '$title'; plot '> "$combined" - else - # clear old one: - printf "%0.s\033[1A\033[K" $(seq 0 $((num_lines_last_chart + 1))) - num_lines_last_chart=$(echo -e "$chart" | wc -l) - # show this one: - echo -e "$chart" - read -rsp $'Press any key to view the next chart, or CTRL + C to exit ...\n' -n1 key - fi - done 3< "$tmp_values" - done - fi - - # done: + # remove tmp file and change back to original branch and then we're done + rm -f '$tmp_values' + git checkout $current_branch exit 0 fi else From 9d7865733f30a7978b2d886c8b9afbb4832b3cdd Mon Sep 17 00:00:00 2001 From: kodonnell Date: Wed, 7 Dec 2016 07:33:14 +1300 Subject: [PATCH 22/22] tidied up doco a bit --- map-matching.sh | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/map-matching.sh b/map-matching.sh index 9f5cd019..236b6a0e 100755 --- a/map-matching.sh +++ b/map-matching.sh @@ -32,11 +32,26 @@ elif [ "$1" = "action=test" ]; then # return exit code of mvn exit $? elif [ "$1" = "action=measurement" ]; then + # the purpose of this is to run the com.graphhopper.matching.util.Measurement suite, which outputs + # measurement files locally. Usage is either + # + # ./map-matching.sh action=measurement map.osm.pbf + # + # which just compiles the current source and exports the measurement file, or + # + # ./map-matching.sh action=measurement map.osm.pbf 3 + # + # which (in this case) runs the measurement suite for the last 3 commits. (This involves checking them + # out and building one-by-one, which is quite slow.) + # TODO: cache some of the builds/tests to speed things up if the developer's looking for quick feedback + # TODO: figure out a way to genericise this - see GH PR 894 + # TODO: add an error quantification (e.g. std) to the measurement class (inc. in GH), and add it to the outputs (inc. plots) + set_jar "core" ARGS="config=$CONFIG graph.location=$GRAPH datareader.file=$2 prepare.ch.weightings=fastest graph.flag_encoders=car prepare.min_network_size=10000 prepare.min_oneway_network_size=10000" current_branch=$(git rev-parse --abbrev-ref HEAD) function startMeasurement { - echo -e "\nperforming measurement for commit $current_commit" + # runs a measurement for the current code base mvn --projects matching-core -DskipTests=true clean install assembly:single measurement_fname="measurement$(date +%Y-%m-%d_%H_%M_%S).properties" "$JAVA" $JAVA_OPTS -cp "$JAR" com.graphhopper.matching.util.Measurement $ARGS measurement.location="$measurement_fname" @@ -44,15 +59,15 @@ elif [ "$1" = "action=measurement" ]; then # use all versions starting from HEAD last_commits=$3 - if [ -z "$last_commits" ]; then + if [ -z "$last_commits" ] || [ "$last_commits" -eq 1 ]; then startMeasurement echo "" cat "$measurement_fname" exit 0 else - # the following checks out the last commits, and tests each one. The code looks a bit + # as above, let's check out, build, and test each of the last commits. The code looks a bit # messier than that, as we merge the results into a single file (to make it easier to - # compare. + # comparem measurements) combined="measurement_$(git log --format="%h" | head -n $last_commits | tail -n1)_$(git log --format="%h" | head -n1).properties" tmp_values="$combined.values" rm -f "$tmp_values" @@ -75,12 +90,15 @@ elif [ "$1" = "action=measurement" ]; then key=${line%%=*} value=$(printf "%-20s" "${line##*=}") if [ "$first" = true ] ; then + # first commit, so print key and value printf "%-30s%s\n" "$key" "$value" >> "$tmp_values" else if grep "$key" "$tmp_values" > /dev/null; then + # second (or later) commit, in which key already exists, so we simply append it + # TODO: this may fail if e.g. a key exists in commit 1, not in commit 2, and then again in commit 3 ... pretty unlikely sed -ri "s/($key.*)/\1$value/g" "$tmp_values" else - # add a new row, using $empty_pad to get the column in the right place + # second (or later) commit, in which a new key has appeeard - so add a new line printf "%-30s%s%s\n" "$key" "$empty_pad" "$value" >> "$tmp_values" fi fi @@ -93,7 +111,7 @@ elif [ "$1" = "action=measurement" ]; then echo "$subheader" >> "$combined" cat "$tmp_values" >> "$combined" - # show as is: + # show to user now: echo "" cat "$combined"