All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opentripplanner.graph_builder.module.map.BusRouteStreetMatcher Maven / Gradle / Ivy

package org.opentripplanner.graph_builder.module.map;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import javax.inject.Inject;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.LineString;
import org.opentripplanner.graph_builder.model.GraphBuilderModule;
import org.opentripplanner.routing.graph.Edge;
import org.opentripplanner.routing.graph.Graph;
import org.opentripplanner.transit.model.network.Route;
import org.opentripplanner.transit.model.network.TripPattern;
import org.opentripplanner.transit.service.TransitModel;
import org.opentripplanner.util.geometry.GeometryUtils;
import org.opentripplanner.util.logging.ProgressTracker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Uses the shapes from GTFS to determine which streets buses drive on. This is used to improve the
 * quality of the shapes shown for the user.
 * 

* GTFS provides a mapping from trips→shapes. This module provides a mapping from stops→trips and * shapes→edges. Then transitively we get a mapping from stop→edges. */ public class BusRouteStreetMatcher implements GraphBuilderModule { private static final Logger log = LoggerFactory.getLogger(BusRouteStreetMatcher.class); private final Graph graph; private final TransitModel transitModel; @Inject public BusRouteStreetMatcher(Graph graph, TransitModel transitModel) { this.graph = graph; this.transitModel = transitModel; } public void buildGraph() { // Mapbuilder needs transit index transitModel.index(); graph.index(transitModel.getStopModel()); StreetMatcher matcher = new StreetMatcher(graph); log.info("Finding corresponding street edges for trip patterns..."); // Why do we need to iterate over the routes? Why not just patterns? Collection allRoutes = transitModel.getTransitModelIndex().getAllRoutes(); // Track progress ProgressTracker progress = ProgressTracker.track( "Match route to street edges", 10, allRoutes.size() ); log.info(progress.startMessage()); for (Route route : allRoutes) { for (TripPattern pattern : transitModel .getTransitModelIndex() .getPatternsForRoute() .get(route)) { if (pattern.getMode().onStreet()) { /* we can only match geometry to streets on bus routes */ log.debug("Matching {}", pattern); //If there are no shapes in GTFS pattern geometry is generated //generated geometry is useless for street matching //that is why pattern.geometry is null in that case if (pattern.getGeometry() == null) { continue; } for (int i = 0; i < pattern.numHopGeometries(); i++) { LineString hopGeometry = pattern.getHopGeometry(i); List edges = matcher.match(hopGeometry); if (edges == null || edges.isEmpty()) { log.warn("Could not match to street network: {}", pattern); continue; } List coordinates = new ArrayList<>(); for (Edge e : edges) { coordinates.addAll(Arrays.asList(e.getGeometry().getCoordinates())); } Coordinate[] coordinateArray = new Coordinate[coordinates.size()]; LineString ls = GeometryUtils .getGeometryFactory() .createLineString(coordinates.toArray(coordinateArray)); // Replace the hop's geometry from GTFS with that of the equivalent OSM edges. pattern.setHopGeometry(i, ls); } } } progress.step(log::info); } log.info(progress.completeMessage()); } @Override public void checkInputs() { //no file inputs } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy