I am running OTP 1.5 with some GTFS flex data, and it kept throwing a java.util.NoSuchElementException thrown when trying to start OTP. The error stack is like this:
19:54:04.746 INFO (FlexIndex.java:40) initializing hops-for-edge map...
19:54:06.625 INFO (FlexIndex.java:57) Finding corresponding street edges for trip patterns...
Exception in thread "main" java.util.NoSuchElementException
at java.base/java.util.TreeMap$PrivateEntryIterator.nextEntry(TreeMap.java:1206)
at java.base/java.util.TreeMap$ValueIterator.next(TreeMap.java:1253)
at org.opentripplanner.routing.flex.FlexIndex.findClosestEdges(FlexIndex.java:129)
at org.opentripplanner.routing.flex.FlexIndex.initializeHopsForEdgeMap(FlexIndex.java:72)
at org.opentripplanner.routing.flex.FlexIndex.init(FlexIndex.java:41)
at org.opentripplanner.routing.graph.Graph.setUseFlexService(Graph.java:1089)
at org.opentripplanner.standalone.Router.startup(Router.java:160)
at org.opentripplanner.routing.impl.MemoryGraphSource.reload(MemoryGraphSource.java:55)
at org.opentripplanner.routing.services.GraphService.registerGraph(GraphService.java:183)
at org.opentripplanner.standalone.OTPMain.run(OTPMain.java:109)
at org.opentripplanner.standalone.OTPMain.main(OTPMain.java:73)
I tracked the error down and it looks like this is the code in FlexIndex.java that has a bug,
Collection<Edge> edges = graph.streetIndex.getEdgesForEnvelope(env);
if (edges.isEmpty()) {
return Collections.emptyList();
}
Map<Double, List<StreetEdge>> edgeDistanceMap = new TreeMap<>();
for(Edge edge : edges){
if(edge instanceof StreetEdge){
LineString line = edge.getGeometry();
double dist = SphericalDistanceLibrary.fastDistance(pointLocation, line);
double roundOff = (double) Math.round(dist * 100) / 100;
if(!edgeDistanceMap.containsKey(roundOff))
edgeDistanceMap.put(roundOff, new ArrayList<>());
edgeDistanceMap.get(roundOff).add((StreetEdge) edge);
}
}
List<Edge> closestEdges = edgeDistanceMap.values().iterator().next()
.stream().map(e -> (Edge) e).collect(Collectors.toList());
return closestEdges;
Because edgeDistanceMap is empty, b/c the edges are all StreetTransitLink and not StreetEdge objects. I think a fix would be top change the last few lines to:
if(!edgeDistanceMap.isEmpty()) {
List<Edge> closestEdges = edgeDistanceMap.values().iterator().next()
.stream().map(e -> (Edge) e).collect(Collectors.toList());
return closestEdges;
}
else{
return new ArrayList<>(edges);
}
Does this look about right for a fix? Or is this a problem with the flex data?