/** * Finds direct paths between from and to coordinates in request and adds them to option * * @param request * @param option */ private void findDirectPaths(ProfileRequest request, ProfileOption option) { // For direct modes for (LegMode mode : request.directModes) { StreetRouter streetRouter = new StreetRouter(transportNetwork.streetLayer); StreetPath streetPath; streetRouter.profileRequest = request; if (mode == LegMode.BICYCLE_RENT) { if (!transportNetwork.streetLayer.bikeSharing) { LOG.warn("Bike sharing trip requested but no bike sharing stations in the streetlayer"); continue; } streetRouter = findBikeRentalPath(request, streetRouter, true); if (streetRouter != null) { StreetRouter.State lastState = streetRouter.getState(request.toLat, request.toLon); if (lastState != null) { streetPath = new StreetPath(lastState, streetRouter, LegMode.BICYCLE_RENT, transportNetwork); } else { LOG.warn( "MODE:{}, Edge near the destination coordinate wasn't found. Routing didn't start!", mode); continue; } } else { LOG.warn("Not found path from cycle to end"); continue; } } else { streetRouter.streetMode = StreetMode.valueOf(mode.toString()); streetRouter.timeLimitSeconds = request.streetTime * 60; if (streetRouter.setOrigin(request.fromLat, request.fromLon)) { if (!streetRouter.setDestination(request.toLat, request.toLon)) { LOG.warn("Direct mode {} destination wasn't found!", mode); continue; } streetRouter.route(); StreetRouter.State lastState = streetRouter.getState(streetRouter.getDestinationSplit()); if (lastState == null) { LOG.warn("Direct mode {} last state wasn't found", mode); continue; } streetPath = new StreetPath(lastState, transportNetwork); } else { LOG.warn("Direct mode {} origin wasn't found!", mode); continue; } } StreetSegment streetSegment = new StreetSegment(streetPath, mode, transportNetwork.streetLayer); option.addDirect(streetSegment, request.getFromTimeDateZD()); } }
/** * Uses 3 streetSearches to first search from fromLat/fromLon to all the bike renting places in * WALK mode. Then from all found bike renting places to other bike renting places with BIKE and * then just routing from those found bike renting places in WALK mode. * * <p>This can then be used as streetRouter for access paths or as a direct search for specific * destination * * <p>Last streetRouter (WALK from bike rentals) is returned * * @param request profileRequest from which from/to destination is used * @param streetRouter where profileRequest was already set * @param direct * @return null if path isn't found */ private StreetRouter findBikeRentalPath( ProfileRequest request, StreetRouter streetRouter, boolean direct) { streetRouter.streetMode = StreetMode.WALK; // TODO add time and distance limits to routing, not just weight. streetRouter.timeLimitSeconds = request.maxWalkTime * 60; if (!direct) { streetRouter.dominanceVariable = StreetRouter.State.RoutingVariable.DURATION_SECONDS; } streetRouter.flagSearch = VertexStore.VertexFlag.BIKE_SHARING; if (streetRouter.setOrigin(request.fromLat, request.fromLon)) { // if we can't find destination we can stop search before even trying if (direct && !streetRouter.setDestination(request.toLat, request.toLon)) { return null; } Split destinationSplit = streetRouter.getDestinationSplit(); // reset destinationSplit since we need it at the last part of routing streetRouter.setDestination(null); streetRouter.route(); // This finds all the nearest bicycle rent stations when walking TIntObjectMap<StreetRouter.State> bikeStations = streetRouter.getReachedVertices(VertexStore.VertexFlag.BIKE_SHARING); LOG.info( "BIKE RENT: Found {} bike stations which are {} minutes away", bikeStations.size(), streetRouter.timeLimitSeconds / 60); /*LOG.info("Start to bike share:"); bikeStations.forEachEntry((idx, state) -> { LOG.info(" {} ({}m)", idx, state.distance); return true; });*/ // This finds best cycling path from best start bicycle station to end bicycle station StreetRouter bicycle = new StreetRouter(transportNetwork.streetLayer); bicycle.previousRouter = streetRouter; bicycle.streetMode = StreetMode.BICYCLE; bicycle.profileRequest = request; bicycle.flagSearch = streetRouter.flagSearch; bicycle.maxVertices = Integer.MAX_VALUE; // Longer bike part if this is direct search if (direct) { bicycle.timeLimitSeconds = request.streetTime * 60; } else { bicycle.timeLimitSeconds = request.maxBikeTime * 60; bicycle.dominanceVariable = StreetRouter.State.RoutingVariable.DURATION_SECONDS; } bicycle.setOrigin( bikeStations, BIKE_RENTAL_PICKUP_TIME_S, BIKE_RENTAL_PICKUP_COST, LegMode.BICYCLE_RENT); bicycle.setDestination(destinationSplit); bicycle.route(); TIntObjectMap<StreetRouter.State> cycledStations = bicycle.getReachedVertices(VertexStore.VertexFlag.BIKE_SHARING); LOG.info( "BIKE RENT: Found {} cycled stations which are {} minutes away", cycledStations.size(), bicycle.timeLimitSeconds / 60); /*LOG.info("Bike share to bike share:"); cycledStations.retainEntries((idx, state) -> { if (bikeStations.containsKey(idx)) { LOG.warn(" MM:{} ({}m)", idx, state.distance/1000); return false; } else { LOG.info(" {} ({}m)", idx, state.distance / 1000); return true; } });*/ // This searches for walking path from end bicycle station to end point StreetRouter end = new StreetRouter(transportNetwork.streetLayer); end.streetMode = StreetMode.WALK; end.profileRequest = request; end.timeLimitSeconds = bicycle.timeLimitSeconds; if (!direct) { end.transitStopSearch = true; end.dominanceVariable = StreetRouter.State.RoutingVariable.DURATION_SECONDS; } end.setOrigin( cycledStations, BIKE_RENTAL_DROPOFF_TIME_S, BIKE_RENTAL_DROPOFF_COST, LegMode.BICYCLE_RENT); end.route(); end.previousRouter = bicycle; return end; } else { return null; } }