Skip to content

Commit

Permalink
Merge pull request #6047 from Skanetrafiken/access-egress-station-rou…
Browse files Browse the repository at this point in the history
…ting

Support for routing to Station centroid instead of child stops
  • Loading branch information
habrahamsson-skanetrafiken authored Oct 8, 2024
2 parents b60f98f + a8674a9 commit 45f3e5b
Show file tree
Hide file tree
Showing 76 changed files with 1,440 additions and 375 deletions.
213 changes: 117 additions & 96 deletions doc/user/BuildConfiguration.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.opentripplanner.street.model.edge.EscalatorEdge;
import org.opentripplanner.street.model.edge.PathwayEdge;
import org.opentripplanner.street.model.edge.StreetEdge;
import org.opentripplanner.street.model.edge.StreetStationCentroidLink;
import org.opentripplanner.street.model.edge.StreetTransitEntranceLink;
import org.opentripplanner.street.model.edge.StreetTransitStopLink;
import org.opentripplanner.street.model.edge.StreetVehicleParkingLink;
Expand Down Expand Up @@ -109,7 +110,8 @@ static StyleSpec build(
StreetTransitEntranceLink.class,
BoardingLocationToStopLink.class,
StreetVehicleRentalLink.class,
StreetVehicleParkingLink.class
StreetVehicleParkingLink.class,
StreetStationCentroidLink.class
)
.lineWidth(LINE_WIDTH)
.minZoom(13)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.util.Map;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -199,6 +200,7 @@ public boolean isOff() {
/**
* If feature is turned on, then return supplied object if not return {@code null}.
*/
@Nullable
public <T> T isOnElseNull(Supplier<T> supplier) {
return isOn() ? supplier.get() : null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,20 @@ public static double metersToLonDegrees(double distanceMeters, double latDeg) {
return dLatDeg / minCosLat;
}

/**
* Approximately move a coordinate a given number of meters. This will fail if crossing the anti-
* meridian or any of the poles.
*/
public static WgsCoordinate moveMeters(
WgsCoordinate coordinate,
double latMeters,
double lonMeters
) {
var degreesLat = metersToDegrees(latMeters);
var degreesLon = metersToLonDegrees(lonMeters, coordinate.latitude());
return coordinate.add(degreesLat, degreesLon);
}

public static Envelope bounds(double lat, double lon, double latDistance, double lonDistance) {
double radiusOfEarth = RADIUS_OF_EARTH_IN_M;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,34 @@ public WgsCoordinate roundToApproximate100m() {
return new WgsCoordinate(lat, lng);
}

/**
* Return a new coordinate that is moved an approximate number of meters east.
*/
public WgsCoordinate moveEastMeters(double meters) {
return SphericalDistanceLibrary.moveMeters(this, 0, meters);
}

/**
* Return a new coordinate that is moved an approximate number of meters west.
*/
public WgsCoordinate moveWestMeters(double meters) {
return SphericalDistanceLibrary.moveMeters(this, 0, -meters);
}

/**
* Return a new coordinate that is moved an approximate number of meters north.
*/
public WgsCoordinate moveNorthMeters(double meters) {
return SphericalDistanceLibrary.moveMeters(this, meters, 0);
}

/**
* Return a new coordinate that is moved an approximate number of meters south.
*/
public WgsCoordinate moveSouthMeters(double meters) {
return SphericalDistanceLibrary.moveMeters(this, -meters, 0);
}

/**
* Return a string on the form: {@code "(60.12345, 11.12345)"}. Up to 5 digits are used after the
* period(.), even if the coordinate is specified with a higher precision.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@ public static GraphBuilder create(
graphBuilder.addModule(factory.emissionsModule());
}

graphBuilder.addModuleOptional(factory.routeToCentroidStationIdValidator());

if (config.dataImportReport) {
graphBuilder.addModule(factory.dataImportIssueReporter());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import org.opentripplanner.transit.model.site.PathwayMode;
import org.opentripplanner.transit.model.site.PathwayNode;
import org.opentripplanner.transit.model.site.RegularStop;
import org.opentripplanner.transit.model.site.Station;
import org.opentripplanner.transit.model.site.StationElement;
import org.opentripplanner.transit.model.site.StopLocation;
import org.opentripplanner.transit.service.TransitModel;
Expand Down Expand Up @@ -86,6 +87,7 @@ private void applyToGraph(TransitModel transitModel) {

addStopsToGraphAndGenerateStopVertexes(transitModel);
addEntrancesToGraph();
addStationCentroidsToGraph();
addPathwayNodesToGraph();
addBoardingAreasToGraph();

Expand Down Expand Up @@ -142,6 +144,14 @@ private void addEntrancesToGraph() {
}
}

private void addStationCentroidsToGraph() {
for (Station station : otpTransitService.stopModel().listStations()) {
if (station.shouldRouteToCentroid()) {
vertexFactory.stationCentroid(station);
}
}
}

private void addPathwayNodesToGraph() {
for (PathwayNode node : otpTransitService.getAllPathwayNodes()) {
TransitPathwayNodeVertex nodeVertex = vertexFactory.transitPathwayNode(node);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,7 @@ public void buildGraph() {
LOG.debug("Linking stop '{}' {}", stop, ts0);

for (RouteRequest transferProfile : transferRequests) {
for (NearbyStop sd : findNearbyStops(
nearbyStopFinder,
for (NearbyStop sd : nearbyStopFinder.findNearbyStops(
ts0,
transferProfile,
transferProfile.journey().transfer(),
Expand All @@ -126,8 +125,7 @@ public void buildGraph() {
if (OTPFeature.FlexRouting.isOn()) {
// This code is for finding transfers from AreaStops to Stops, transfers
// from Stops to AreaStops and between Stops are already covered above.
for (NearbyStop sd : findNearbyStops(
nearbyStopFinder,
for (NearbyStop sd : nearbyStopFinder.findNearbyStops(
ts0,
transferProfile,
transferProfile.journey().transfer(),
Expand Down Expand Up @@ -203,15 +201,5 @@ private NearbyStopFinder createNearbyStopFinder() {
}
}

private static Iterable<NearbyStop> findNearbyStops(
NearbyStopFinder nearbyStopFinder,
Vertex vertex,
RouteRequest request,
StreetRequest streetRequest,
boolean reverseDirection
) {
return nearbyStopFinder.findNearbyStops(vertex, request, streetRequest, reverseDirection);
}

private record TransferKey(StopLocation source, StopLocation target, List<Edge> edges) {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package org.opentripplanner.graph_builder.module;

import java.util.Collection;
import java.util.stream.Collectors;
import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore;
import org.opentripplanner.graph_builder.model.GraphBuilderModule;
import org.opentripplanner.transit.model.framework.AbstractTransitEntity;
import org.opentripplanner.transit.model.framework.FeedScopedId;
import org.opentripplanner.transit.service.TransitModel;

public class RouteToCentroidStationIdsValidator implements GraphBuilderModule {

private final DataImportIssueStore issueStore;
private final Collection<FeedScopedId> transitRouteToStationCentroid;
private final TransitModel transitModel;

public RouteToCentroidStationIdsValidator(
DataImportIssueStore issueStore,
Collection<FeedScopedId> transitRouteToStationCentroid,
TransitModel transitModel
) {
this.issueStore = issueStore;
this.transitRouteToStationCentroid = transitRouteToStationCentroid;
this.transitModel = transitModel;
}

private void validate() {
var stationIds = transitModel
.getStopModel()
.listStations()
.stream()
.map(AbstractTransitEntity::getId)
.collect(Collectors.toSet());
transitRouteToStationCentroid
.stream()
.filter(id -> !stationIds.contains(id))
.forEach(id ->
issueStore.add(
"UnknownStationId",
"Config parameter 'transitRouteToStationCentroid' specified a station that does not exist: %s",
id
)
);
}

@Override
public void buildGraph() {
validate();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import org.opentripplanner.framework.application.OTPFeature;
Expand All @@ -15,14 +16,17 @@
import org.opentripplanner.routing.vehicle_parking.VehicleParking;
import org.opentripplanner.routing.vehicle_parking.VehicleParkingHelper;
import org.opentripplanner.street.model.edge.Edge;
import org.opentripplanner.street.model.edge.StreetStationCentroidLink;
import org.opentripplanner.street.model.edge.StreetTransitEntranceLink;
import org.opentripplanner.street.model.edge.StreetTransitStopLink;
import org.opentripplanner.street.model.edge.StreetVehicleParkingLink;
import org.opentripplanner.street.model.edge.VehicleParkingEdge;
import org.opentripplanner.street.model.vertex.StationCentroidVertex;
import org.opentripplanner.street.model.vertex.StreetVertex;
import org.opentripplanner.street.model.vertex.TransitEntranceVertex;
import org.opentripplanner.street.model.vertex.TransitStopVertex;
import org.opentripplanner.street.model.vertex.VehicleParkingEntranceVertex;
import org.opentripplanner.street.model.vertex.Vertex;
import org.opentripplanner.street.search.TraverseMode;
import org.opentripplanner.street.search.TraverseModeSet;
import org.opentripplanner.transit.model.site.GroupStop;
Expand Down Expand Up @@ -70,6 +74,7 @@ public void buildGraph() {
if (graph.hasStreets) {
linkTransitStops(graph, transitModel);
linkTransitEntrances(graph);
linkStationCentroids(graph);
linkVehicleParks(graph, issueStore);
}

Expand Down Expand Up @@ -257,6 +262,34 @@ private void linkTransitEntrances(Graph graph) {
}
}

private void linkStationCentroids(Graph graph) {
BiFunction<Vertex, StreetVertex, List<Edge>> stationAndStreetVertexLinker = (
theStation,
streetVertex
) ->
List.of(
StreetStationCentroidLink.createStreetStationLink(
(StationCentroidVertex) theStation,
streetVertex
),
StreetStationCentroidLink.createStreetStationLink(
streetVertex,
(StationCentroidVertex) theStation
)
);

for (StationCentroidVertex station : graph.getVerticesOfType(StationCentroidVertex.class)) {
graph
.getLinker()
.linkVertexPermanently(
station,
new TraverseModeSet(TraverseMode.WALK),
LinkingDirection.BOTH_WAYS,
stationAndStreetVertexLinker
);
}
}

private void linkVehicleParks(Graph graph, DataImportIssueStore issueStore) {
LOG.info("Linking vehicle parks to graph...");
List<VehicleParking> vehicleParkingToRemove = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.opentripplanner.graph_builder.module.DirectTransferGenerator;
import org.opentripplanner.graph_builder.module.GraphCoherencyCheckerModule;
import org.opentripplanner.graph_builder.module.OsmBoardingLocationsModule;
import org.opentripplanner.graph_builder.module.RouteToCentroidStationIdsValidator;
import org.opentripplanner.graph_builder.module.StreetLinkerModule;
import org.opentripplanner.graph_builder.module.TimeZoneAdjusterModule;
import org.opentripplanner.graph_builder.module.TripPatternNamer;
Expand Down Expand Up @@ -58,6 +59,9 @@ public interface GraphBuilderFactory {
CalculateWorldEnvelopeModule calculateWorldEnvelopeModule();
StreetLimitationParameters streetLimitationParameters();

@Nullable
RouteToCentroidStationIdsValidator routeToCentroidStationIdValidator();

@Nullable
StopConsolidationModule stopConsolidationModule();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.opentripplanner.graph_builder.issue.report.DataImportIssueReporter;
import org.opentripplanner.graph_builder.issue.service.DefaultDataImportIssueStore;
import org.opentripplanner.graph_builder.module.DirectTransferGenerator;
import org.opentripplanner.graph_builder.module.RouteToCentroidStationIdsValidator;
import org.opentripplanner.graph_builder.module.StreetLinkerModule;
import org.opentripplanner.graph_builder.module.islandpruning.PruneIslands;
import org.opentripplanner.graph_builder.module.ned.DegreeGridNEDTileSource;
Expand Down Expand Up @@ -302,6 +303,20 @@ static StopConsolidationModule providesStopConsolidationModule(
.orElse(null);
}

@Provides
@Singleton
@Nullable
static RouteToCentroidStationIdsValidator routeToCentroidStationIdValidator(
DataImportIssueStore issueStore,
BuildConfig config,
TransitModel transitModel
) {
var ids = config.transitRouteToStationCentroid();
return ids.isEmpty()
? null
: new RouteToCentroidStationIdsValidator(issueStore, ids, transitModel);
}

/* private methods */

private static ElevationGridCoverageFactory createNedElevationFactory(
Expand Down
Loading

0 comments on commit 45f3e5b

Please sign in to comment.