Skip to content

Commit 1186004

Browse files
committed
Merge remote-tracking branch 'upstream/dev-2.x' into move-nearby-stop-finder
2 parents 431f087 + 73bd289 commit 1186004

152 files changed

Lines changed: 7859 additions & 7163 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

application/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@
288288
<dependency>
289289
<groupId>org.onebusaway</groupId>
290290
<artifactId>onebusaway-gtfs</artifactId>
291-
<version>11.2.2</version>
291+
<version>12.0.1</version>
292292
</dependency>
293293
<!-- Used in DegreeGridNEDTileSource to fetch tiles from Amazon S3 -->
294294
<dependency>

application/src/ext/java/org/opentripplanner/ext/flex/FlexRouter.java

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
import org.opentripplanner.framework.application.OTPRequestTimeoutException;
2525
import org.opentripplanner.model.plan.Itinerary;
2626
import org.opentripplanner.place.api.NearbyStop;
27-
import org.opentripplanner.routing.algorithm.mapping.GraphPathToItineraryMapper;
27+
import org.opentripplanner.routing.algorithm.mapping.LegsToItineraryMapper;
28+
import org.opentripplanner.routing.algorithm.mapping.StreetPathToLegsMapper;
2829
import org.opentripplanner.routing.api.request.RouteRequest;
2930
import org.opentripplanner.service.streetdetails.StreetDetailsService;
3031
import org.opentripplanner.street.graph.Graph;
@@ -53,7 +54,7 @@ public class FlexRouter {
5354
private final FlexIndex flexIndex;
5455
private final FlexPathCalculator accessFlexPathCalculator;
5556
private final FlexPathCalculator egressFlexPathCalculator;
56-
private final GraphPathToItineraryMapper graphPathToItineraryMapper;
57+
private final StreetPathToLegsMapper streetPathToLegsMapper;
5758
private final FlexAccessEgressCallbackAdapter callbackService;
5859

5960
/* Request data */
@@ -89,7 +90,7 @@ public FlexRouter(
8990
transitService.getCalendarService()::getServiceDatesForServiceId
9091
);
9192
this.callbackService = new CallbackAdapter();
92-
this.graphPathToItineraryMapper = new GraphPathToItineraryMapper(
93+
this.streetPathToLegsMapper = new StreetPathToLegsMapper(
9394
new TransitServiceResolver(transitService),
9495
transitService.getTimeZone(),
9596
graph.streetNotesService,
@@ -143,13 +144,10 @@ public List<Itinerary> createFlexOnlyItineraries(boolean arriveBy, RouteRequest
143144

144145
for (DirectFlexPath it : directFlexPaths) {
145146
var startTime = startOfTime.plusSeconds(it.startTime());
146-
var itinerary = graphPathToItineraryMapper
147-
.generateItinerary(new StreetPath(it.state()), request)
148-
.withTimeShiftToStartAt(startTime);
149-
150-
if (itinerary != null) {
151-
itineraries.add(itinerary);
152-
}
147+
var path = new StreetPath(it.state());
148+
var legs = streetPathToLegsMapper.map(path, request, startTime);
149+
var itinerary = LegsToItineraryMapper.map(legs, false, path.calculateElevations());
150+
itinerary.ifPresent(itineraries::add);
153151
}
154152
return itineraries;
155153
}

application/src/main/java/org/opentripplanner/apis/transmodel/model/stop/QuayAtDistanceType.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import graphql.schema.GraphQLOutputType;
1010
import java.util.Optional;
1111
import org.opentripplanner.api.model.transit.FeedScopedIdMapper;
12-
import org.opentripplanner.apis.gtfs.GraphQLRequestContext;
12+
import org.opentripplanner.apis.transmodel.TransmodelRequestContext;
1313
import org.opentripplanner.place.api.NearbyStop;
1414
import org.opentripplanner.transit.service.TransitService;
1515

@@ -61,6 +61,6 @@ public GraphQLObjectType createQD(GraphQLOutputType quayType, Relay relay) {
6161
}
6262

6363
private TransitService getTransitService(DataFetchingEnvironment environment) {
64-
return environment.<GraphQLRequestContext>getContext().transitService();
64+
return environment.<TransmodelRequestContext>getContext().getTransitService();
6565
}
6666
}

application/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/DatedServiceJourneyType.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,21 @@ public GraphQLObjectType create(
7272
.field(
7373
GraphQLFieldDefinition.newFieldDefinition()
7474
.name("tripAlteration")
75-
.description("Alterations specified on the Trip in the planned data")
75+
.description(
76+
"Alterations specified on the Trip in the planned data. Note: realtime alterations are not included"
77+
)
7678
.type(EnumTypes.SERVICE_ALTERATION)
7779
.dataFetcher(environment -> tripOnServiceDate(environment).getTripAlteration())
7880
)
81+
.field(
82+
GraphQLFieldDefinition.newFieldDefinition()
83+
.name("extraJourney")
84+
.description(
85+
"Whether this is an extra journey, either from planned data or added in realtime"
86+
)
87+
.type(new GraphQLNonNull(Scalars.GraphQLBoolean))
88+
.dataFetcher(environment -> tripOnServiceDate(environment).isExtraJourney())
89+
)
7990
.field(
8091
GraphQLFieldDefinition.newFieldDefinition()
8192
.name("replacementFor")

application/src/main/java/org/opentripplanner/apis/vectortiles/DebugStyleSpec.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,8 @@ private static List<StyleBuilder> stops(
223223
.fillOpacity(0.5f)
224224
.fillOutlineColor(BLACK)
225225
.minZoom(6)
226-
.maxZoom(MAX_ZOOM),
226+
.maxZoom(MAX_ZOOM)
227+
.intiallyHidden(),
227228
StyleBuilder.ofId("group-stop")
228229
.group(STOPS_GROUP)
229230
.typeFill()
@@ -232,7 +233,8 @@ private static List<StyleBuilder> stops(
232233
.fillOpacity(0.5f)
233234
.fillOutlineColor(BLACK)
234235
.minZoom(6)
235-
.maxZoom(MAX_ZOOM),
236+
.maxZoom(MAX_ZOOM)
237+
.intiallyHidden(),
236238
StyleBuilder.ofId("regular-stop")
237239
.group(STOPS_GROUP)
238240
.typeCircle()

application/src/main/java/org/opentripplanner/graph_builder/issues/ElevationFlattened.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22

33
import org.locationtech.jts.geom.Geometry;
44
import org.opentripplanner.graph_builder.issue.api.DataImportIssue;
5+
import org.opentripplanner.graph_builder.issue.api.OsmUrlGenerator;
56
import org.opentripplanner.street.model.edge.Edge;
67

78
public record ElevationFlattened(Edge edge) implements DataImportIssue {
8-
private static final String FMT = "Edge %s was steeper than Baldwin Street and was flattened.";
9+
private static final String FMT = "Edge %s was steeper than 35 percent and flattened.";
910

1011
@Override
1112
public String getMessage() {
@@ -16,4 +17,12 @@ public String getMessage() {
1617
public Geometry getGeometry() {
1718
return edge.getGeometry();
1819
}
20+
21+
@Override
22+
public String getHTMLMessage() {
23+
return "<a href='%s'>Edge %s</a> was steeper than 35 percent and flattened.".formatted(
24+
OsmUrlGenerator.fromCoordinate(edge.getFromVertex().getCoordinate()),
25+
edge.getName()
26+
);
27+
}
1928
}

application/src/main/java/org/opentripplanner/graph_builder/module/configure/GraphBuilderModules.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,8 @@ private static ElevationModule createElevationModule(
420420
config.distanceBetweenElevationSamples,
421421
config.maxElevationPropagationMeters,
422422
config.includeEllipsoidToGeoidDifference,
423-
config.multiThreadElevationCalculations
423+
config.multiThreadElevationCalculations,
424+
config.elevationTileCacheSizeMB
424425
);
425426
}
426427

application/src/main/java/org/opentripplanner/graph_builder/module/ned/ElevationModule.java

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
import java.util.Map;
1919
import java.util.concurrent.ConcurrentHashMap;
2020
import java.util.concurrent.atomic.AtomicInteger;
21+
import org.eclipse.imagen.ImageN;
22+
import org.eclipse.imagen.TileCache;
2123
import org.geotools.api.coverage.Coverage;
2224
import org.geotools.api.coverage.PointOutsideCoverageException;
2325
import org.geotools.api.referencing.crs.CoordinateReferenceSystem;
@@ -62,6 +64,9 @@
6264
public class ElevationModule implements GraphBuilderModule {
6365

6466
private static final Logger LOG = LoggerFactory.getLogger(ElevationModule.class);
67+
68+
private static final long ONE_MEGABYTE = 1024L * 1024L;
69+
6570
/**
6671
* The WGS84 CRS with longitude-first axis order. The first time a CRS lookup is
6772
* performed is surprisingly expensive (around 500ms), apparently due to initializing
@@ -99,6 +104,11 @@ public class ElevationModule implements GraphBuilderModule {
99104
* data and machine settings, it might be faster to use a single processor.
100105
*/
101106
private final boolean multiThreadElevationCalculations;
107+
/**
108+
* Memory budget (in megabytes) for the Imagen tile cache. Applied to
109+
* {@link org.eclipse.imagen.ImageN#getDefaultInstance()} before any tile is fetched.
110+
*/
111+
private final int elevationTileCacheSizeMB;
102112
// Keep track of the proportion of elevation fetch operations that fail so we can issue warnings. AtomicInteger is
103113
// used to provide thread-safe updating capabilities.
104114
private final AtomicInteger nPointsEvaluated = new AtomicInteger(0);
@@ -138,7 +148,8 @@ public ElevationModule(ElevationGridCoverageFactory factory, Graph graph) {
138148
10,
139149
2000,
140150
true,
141-
false
151+
false,
152+
100
142153
);
143154
}
144155

@@ -153,7 +164,8 @@ public ElevationModule(
153164
double distanceBetweenSamplesM,
154165
double maxElevationPropagationMeters,
155166
boolean includeEllipsoidToGeoidDifference,
156-
boolean multiThreadElevationCalculations
167+
boolean multiThreadElevationCalculations,
168+
int elevationTileCacheSizeMB
157169
) {
158170
gridCoverageFactory = factory;
159171
this.graph = graph;
@@ -165,12 +177,14 @@ public ElevationModule(
165177
this.maxElevationPropagationMeters = maxElevationPropagationMeters;
166178
this.includeEllipsoidToGeoidDifference = includeEllipsoidToGeoidDifference;
167179
this.multiThreadElevationCalculations = multiThreadElevationCalculations;
180+
this.elevationTileCacheSizeMB = elevationTileCacheSizeMB;
168181
this.distanceBetweenSamplesM = distanceBetweenSamplesM;
169182
}
170183

171184
@Override
172185
public void buildGraph() {
173186
Instant start = Instant.now();
187+
configureTileCache();
174188
gridCoverageFactory.fetchData(graph);
175189

176190
graph.setDistanceBetweenElevationSamples(this.distanceBetweenSamplesM);
@@ -323,6 +337,28 @@ public void checkInputs() {
323337
}
324338
}
325339

340+
/**
341+
* Resize the Imagen default tile cache to the configured budget. Run once before any DEM tile
342+
* is fetched, so subsequent {@code getTile} calls hit the cache instead of re-decompressing.
343+
* <p>
344+
* Imagen's default cache is 16 MB, which is too small to hold the hot working set on regional
345+
* DEMs and causes the elevation pass to spend most of its time re-decompressing TIFF tiles.
346+
*/
347+
private void configureTileCache() {
348+
long bytes = elevationTileCacheSizeMB * ONE_MEGABYTE;
349+
TileCache cache = ImageN.getDefaultInstance().getTileCache();
350+
long previousBytes = cache.getMemoryCapacity();
351+
if (previousBytes == bytes) {
352+
return;
353+
}
354+
cache.setMemoryCapacity(bytes);
355+
LOG.info(
356+
"Imagen tile cache memory capacity set to {} MB (was {} MB)",
357+
elevationTileCacheSizeMB,
358+
previousBytes / ONE_MEGABYTE
359+
);
360+
}
361+
326362
private void updateElevationMetadata(Graph graph) {
327363
if (nPointsOutsideDEM.get() < nPointsEvaluated.get()) {
328364
graph.hasElevation = true;

application/src/main/java/org/opentripplanner/model/plan/Itinerary.java

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -282,19 +282,6 @@ public boolean hasSystemNoticeTag(String tag) {
282282
return systemNotices.stream().map(SystemNotice::tag).anyMatch(tag::equals);
283283
}
284284

285-
public Itinerary withTimeShiftToStartAt(ZonedDateTime afterTime) {
286-
Duration duration = Duration.between(legs().getFirst().startTime(), afterTime);
287-
List<Leg> timeShiftedLegs = legs()
288-
.stream()
289-
.map(leg -> leg.withTimeShift(duration))
290-
.collect(Collectors.toList());
291-
return new ItineraryBuilder(timeShiftedLegs, searchWindowAware)
292-
.withGeneralizedCost(generalizedCost)
293-
.withAccessPenalty(accessPenalty)
294-
.withEgressPenalty(egressPenalty)
295-
.build();
296-
}
297-
298285
/** Total duration of the itinerary in seconds */
299286
public Duration totalDuration() {
300287
return totalDuration;
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package org.opentripplanner.routing.algorithm.mapping;
2+
3+
import java.util.List;
4+
import java.util.Optional;
5+
import javax.annotation.Nullable;
6+
import org.opentripplanner.core.model.basic.Cost;
7+
import org.opentripplanner.model.plan.Itinerary;
8+
import org.opentripplanner.model.plan.Leg;
9+
import org.opentripplanner.street.model.path.ElevationChange;
10+
11+
public class LegsToItineraryMapper {
12+
13+
public static Optional<Itinerary> map(
14+
List<Leg> legs,
15+
boolean arrivedAtDestinationWithRentedVehicle,
16+
@Nullable ElevationChange elevationChange
17+
) {
18+
if (legs.isEmpty()) {
19+
return Optional.empty();
20+
}
21+
var cost = Cost.costOfSeconds(legs.stream().mapToDouble(Leg::generalizedCost).sum());
22+
var builder = Itinerary.ofDirect(legs).withGeneralizedCost(cost);
23+
24+
builder.withArrivedAtDestinationWithRentedVehicle(arrivedAtDestinationWithRentedVehicle);
25+
if (elevationChange != null) {
26+
builder.addElevationChange(elevationChange);
27+
}
28+
29+
return Optional.of(builder.build());
30+
}
31+
}

0 commit comments

Comments
 (0)