Search in sources :

Example 1 with MapMatching

use of com.graphhopper.matching.MapMatching in project graphhopper by graphhopper.

the class MatchCommand method run.

@Override
protected void run(Bootstrap<GraphHopperServerConfiguration> bootstrap, Namespace args, GraphHopperServerConfiguration configuration) {
    GraphHopperConfig graphHopperConfiguration = configuration.getGraphHopperConfiguration();
    GraphHopper hopper = new GraphHopper().init(graphHopperConfiguration);
    hopper.importOrLoad();
    PMap hints = new PMap();
    hints.putObject("profile", args.get("profile"));
    MapMatching mapMatching = new MapMatching(hopper, hints);
    mapMatching.setTransitionProbabilityBeta(args.getDouble("transition_probability_beta"));
    mapMatching.setMeasurementErrorSigma(args.getInt("gps_accuracy"));
    StopWatch importSW = new StopWatch();
    StopWatch matchSW = new StopWatch();
    Translation tr = new TranslationMap().doImport().getWithFallBack(Helper.getLocale(args.getString("instructions")));
    final boolean withRoute = !args.getString("instructions").isEmpty();
    XmlMapper xmlMapper = new XmlMapper();
    for (File gpxFile : args.<File>getList("gpx")) {
        try {
            importSW.start();
            Gpx gpx = xmlMapper.readValue(gpxFile, Gpx.class);
            if (gpx.trk == null) {
                throw new IllegalArgumentException("No tracks found in GPX document. Are you using waypoints or routes instead?");
            }
            if (gpx.trk.size() > 1) {
                throw new IllegalArgumentException("GPX documents with multiple tracks not supported yet.");
            }
            List<Observation> measurements = GpxConversions.getEntries(gpx.trk.get(0));
            importSW.stop();
            matchSW.start();
            MatchResult mr = mapMatching.match(measurements);
            matchSW.stop();
            System.out.println(gpxFile);
            System.out.println("\tmatches:\t" + mr.getEdgeMatches().size() + ", gps entries:" + measurements.size());
            System.out.println("\tgpx length:\t" + (float) mr.getGpxEntriesLength() + " vs " + (float) mr.getMatchLength());
            String outFile = gpxFile.getAbsolutePath() + ".res.gpx";
            System.out.println("\texport results to:" + outFile);
            ResponsePath responsePath = new PathMerger(mr.getGraph(), mr.getWeighting()).doWork(PointList.EMPTY, Collections.singletonList(mr.getMergedPath()), hopper.getEncodingManager(), tr);
            if (responsePath.hasErrors()) {
                System.err.println("Problem with file " + gpxFile + ", " + responsePath.getErrors());
                continue;
            }
            try (BufferedWriter writer = new BufferedWriter(new FileWriter(outFile))) {
                long time = gpx.trk.get(0).getStartTime().map(Date::getTime).orElse(System.currentTimeMillis());
                writer.append(GpxConversions.createGPX(responsePath.getInstructions(), gpx.trk.get(0).name != null ? gpx.trk.get(0).name : "", time, hopper.hasElevation(), withRoute, true, false, Constants.VERSION, tr));
            }
        } catch (Exception ex) {
            importSW.stop();
            matchSW.stop();
            System.err.println("Problem with file " + gpxFile);
            ex.printStackTrace(System.err);
        }
    }
    System.out.println("gps import took:" + importSW.getSeconds() + "s, match took: " + matchSW.getSeconds());
}
Also used : MapMatching(com.graphhopper.matching.MapMatching) FileWriter(java.io.FileWriter) GraphHopper(com.graphhopper.GraphHopper) MatchResult(com.graphhopper.matching.MatchResult) Gpx(com.graphhopper.jackson.Gpx) GraphHopperConfig(com.graphhopper.GraphHopperConfig) XmlMapper(com.fasterxml.jackson.dataformat.xml.XmlMapper) BufferedWriter(java.io.BufferedWriter) ResponsePath(com.graphhopper.ResponsePath) Observation(com.graphhopper.matching.Observation) File(java.io.File)

Example 2 with MapMatching

use of com.graphhopper.matching.MapMatching in project graphhopper by graphhopper.

the class MapMatchingTest method testLoop.

/**
 * This test is to check that loops are maintained. GPX input:
 * https://graphhopper.com/maps/?point=51.343657%2C12.360708&point=51.344982%2C12.364066&point=51.344841%2C12.361223&point=51.342781%2C12.361867&layer=Lyrk
 */
@ParameterizedTest
@ArgumentsSource(FixtureProvider.class)
public void testLoop(PMap hints) throws IOException {
    MapMatching mapMatching = new MapMatching(graphHopper, hints);
    // Need to reduce GPS accuracy because too many GPX are filtered out otherwise.
    mapMatching.setMeasurementErrorSigma(40);
    Gpx gpx = xmlMapper.readValue(getClass().getResourceAsStream("/tour2-with-loop.gpx"), Gpx.class);
    MatchResult mr = mapMatching.match(GpxConversions.getEntries(gpx.trk.get(0)));
    assertEquals(Arrays.asList("Gustav-Adolf-Straße", "Leibnizstraße", "Hinrichsenstraße", "Tschaikowskistraße"), fetchStreets(mr.getEdgeMatches()));
    assertEquals(mr.getGpxEntriesLength(), mr.getMatchLength(), 5);
}
Also used : MapMatching(com.graphhopper.matching.MapMatching) MatchResult(com.graphhopper.matching.MatchResult) Gpx(com.graphhopper.jackson.Gpx) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) ArgumentsSource(org.junit.jupiter.params.provider.ArgumentsSource)

Example 3 with MapMatching

use of com.graphhopper.matching.MapMatching in project graphhopper by graphhopper.

the class MapMatchingTest method testDistantPoints.

/**
 * This test is to check behavior over large separated routes: it should
 * work if the user sets the maxVisitedNodes large enough. Input path:
 * https://graphhopper.com/maps/?point=51.23%2C12.18&point=51.45%2C12.59&layer=Lyrk
 * <p>
 * Update: Seems to me that this test only tests a long route, not one with
 * distant input points. createRandomGPXEntries currently creates very close input points.
 * The length of the route doesn't seem to matter.
 */
@ParameterizedTest
@ArgumentsSource(FixtureProvider.class)
public void testDistantPoints(PMap hints) {
    // OK with 1000 visited nodes:
    MapMatching mapMatching = new MapMatching(graphHopper, hints);
    ResponsePath route = graphHopper.route(new GHRequest(new GHPoint(51.23, 12.18), new GHPoint(51.45, 12.59)).setProfile("my_profile")).getBest();
    List<Observation> inputGPXEntries = createRandomGPXEntriesAlongRoute(route);
    MatchResult mr = mapMatching.match(inputGPXEntries);
    assertEquals(route.getDistance(), mr.getMatchLength(), 2);
    // GraphHopper travel times aren't exactly additive
    assertThat(Math.abs(route.getTime() - mr.getMatchMillis()), is(lessThan(1000L)));
    // not OK when we only allow a small number of visited nodes:
    PMap opts = new PMap(hints).putObject(Parameters.Routing.MAX_VISITED_NODES, 1);
    mapMatching = new MapMatching(graphHopper, opts);
    try {
        mr = mapMatching.match(inputGPXEntries);
        fail("Expected sequence to be broken due to maxVisitedNodes being too small");
    } catch (RuntimeException e) {
        assertTrue(e.getMessage().startsWith("Sequence is broken for submitted track"));
    }
}
Also used : MapMatching(com.graphhopper.matching.MapMatching) ResponsePath(com.graphhopper.ResponsePath) GHRequest(com.graphhopper.GHRequest) Observation(com.graphhopper.matching.Observation) PMap(com.graphhopper.util.PMap) GHPoint(com.graphhopper.util.shapes.GHPoint) MatchResult(com.graphhopper.matching.MatchResult) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) ArgumentsSource(org.junit.jupiter.params.provider.ArgumentsSource)

Example 4 with MapMatching

use of com.graphhopper.matching.MapMatching in project graphhopper by graphhopper.

the class MapMatchingTest method testDoWork.

/**
 * TODO: split this test up into smaller units with better names?
 */
@ParameterizedTest
@ArgumentsSource(FixtureProvider.class)
public void testDoWork(PMap hints) {
    MapMatching mapMatching = new MapMatching(graphHopper, hints);
    ResponsePath route2 = graphHopper.route(new GHRequest(new GHPoint(51.358735, 12.360574), new GHPoint(51.358594, 12.360032)).setProfile("my_profile")).getBest();
    List<Observation> inputGPXEntries = createRandomGPXEntriesAlongRoute(route2);
    MatchResult mr = mapMatching.match(inputGPXEntries);
    // make sure no virtual edges are returned
    int edgeCount = graphHopper.getGraphHopperStorage().getAllEdges().length();
    for (EdgeMatch em : mr.getEdgeMatches()) {
        assertTrue(em.getEdgeState().getEdge() < edgeCount, "result contains virtual edges:" + em.getEdgeState().toString());
    }
    // create street names
    assertEquals(Arrays.asList("Platnerstraße"), fetchStreets(mr.getEdgeMatches()));
    assertEquals(mr.getGpxEntriesLength(), mr.getMatchLength(), 1.5);
    ResponsePath route1 = graphHopper.route(new GHRequest(new GHPoint(51.33099, 12.380267), new GHPoint(51.330531, 12.380396)).setProfile("my_profile")).getBest();
    inputGPXEntries = createRandomGPXEntriesAlongRoute(route1);
    mapMatching.setMeasurementErrorSigma(5);
    mr = mapMatching.match(inputGPXEntries);
    assertEquals(Arrays.asList("Windmühlenstraße", "Bayrischer Platz"), fetchStreets(mr.getEdgeMatches()));
    assertEquals(mr.getGpxEntriesLength(), mr.getMatchLength(), .1);
    ResponsePath route = graphHopper.route(new GHRequest(new GHPoint(51.377781, 12.338333), new GHPoint(51.323317, 12.387085)).setProfile("my_profile")).getBest();
    inputGPXEntries = createRandomGPXEntriesAlongRoute(route);
    mapMatching = new MapMatching(graphHopper, hints);
    mapMatching.setMeasurementErrorSigma(20);
    mr = mapMatching.match(inputGPXEntries);
    assertEquals(route.getDistance(), mr.getMatchLength(), 0.5);
    // GraphHopper travel times aren't exactly additive
    assertThat(Math.abs(route.getTime() - mr.getMatchMillis()), is(lessThan(1000L)));
    assertEquals(142, mr.getEdgeMatches().size());
}
Also used : MapMatching(com.graphhopper.matching.MapMatching) ResponsePath(com.graphhopper.ResponsePath) EdgeMatch(com.graphhopper.matching.EdgeMatch) GHRequest(com.graphhopper.GHRequest) Observation(com.graphhopper.matching.Observation) GHPoint(com.graphhopper.util.shapes.GHPoint) MatchResult(com.graphhopper.matching.MatchResult) GHPoint(com.graphhopper.util.shapes.GHPoint) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) ArgumentsSource(org.junit.jupiter.params.provider.ArgumentsSource)

Example 5 with MapMatching

use of com.graphhopper.matching.MapMatching in project graphhopper by graphhopper.

the class MapMatchingTest method testUTurns.

/**
 * This test is to check that U-turns are avoided when it's just measurement
 * error, though do occur when a point goes up a road further than the
 * measurement error. GPX input:
 * https://graphhopper.com/maps/?point=51.343618%2C12.360772&point=51.34401%2C12.361776&point=51.343977%2C12.362886&point=51.344734%2C12.36236&point=51.345233%2C12.362055&layer=Lyrk
 */
@ParameterizedTest
@ArgumentsSource(FixtureProvider.class)
public void testUTurns(PMap hints) throws IOException {
    hints = new PMap(hints).putObject(Parameters.Routing.HEADING_PENALTY, 50);
    MapMatching mapMatching = new MapMatching(graphHopper, hints);
    Gpx gpx = xmlMapper.readValue(getClass().getResourceAsStream("/tour4-with-uturn.gpx"), Gpx.class);
    // with large measurement error, we expect no U-turn
    mapMatching.setMeasurementErrorSigma(50);
    MatchResult mr = mapMatching.match(GpxConversions.getEntries(gpx.trk.get(0)));
    assertEquals(Arrays.asList("Gustav-Adolf-Straße", "Funkenburgstraße"), fetchStreets(mr.getEdgeMatches()));
    // with small measurement error, we expect the U-turn
    mapMatching.setMeasurementErrorSigma(10);
    mr = mapMatching.match(GpxConversions.getEntries(gpx.trk.get(0)));
    assertEquals(Arrays.asList("Gustav-Adolf-Straße", "Funkenburgstraße"), fetchStreets(mr.getEdgeMatches()));
}
Also used : MapMatching(com.graphhopper.matching.MapMatching) PMap(com.graphhopper.util.PMap) MatchResult(com.graphhopper.matching.MatchResult) Gpx(com.graphhopper.jackson.Gpx) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) ArgumentsSource(org.junit.jupiter.params.provider.ArgumentsSource)

Aggregations

MapMatching (com.graphhopper.matching.MapMatching)11 MatchResult (com.graphhopper.matching.MatchResult)11 Gpx (com.graphhopper.jackson.Gpx)8 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)7 ArgumentsSource (org.junit.jupiter.params.provider.ArgumentsSource)7 PMap (com.graphhopper.util.PMap)5 GraphHopper (com.graphhopper.GraphHopper)4 ResponsePath (com.graphhopper.ResponsePath)4 EdgeMatch (com.graphhopper.matching.EdgeMatch)4 Observation (com.graphhopper.matching.Observation)4 GHRequest (com.graphhopper.GHRequest)3 LMProfile (com.graphhopper.config.LMProfile)3 Profile (com.graphhopper.config.Profile)3 GHPoint (com.graphhopper.util.shapes.GHPoint)3 Test (org.junit.jupiter.api.Test)3 XmlMapper (com.fasterxml.jackson.dataformat.xml.XmlMapper)1 GraphHopperConfig (com.graphhopper.GraphHopperConfig)1 BufferedWriter (java.io.BufferedWriter)1 File (java.io.File)1 FileWriter (java.io.FileWriter)1