/* This program is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package org.opentripplanner.routing.edgetype;
import org.opentripplanner.routing.core.RoutingRequest;
import org.opentripplanner.routing.core.State;
import org.opentripplanner.routing.core.StateEditor;
import org.opentripplanner.routing.core.TraverseMode;
import org.opentripplanner.routing.graph.Edge;
import org.opentripplanner.routing.vertextype.BikeParkVertex;
import com.vividsolutions.jts.geom.LineString;
import java.util.Locale;
/**
* Parking a bike edge.
*
* Note: There is an edge only in the "park" direction. We do not handle (yet) unparking a bike, as
* you would need to know where you have parked your car, and is probably better handled by the
* client by issuing two requests (first one from your origin to your bike, second one from your
* bike to your destination).
*
* Cost is the time to park a bike, estimated.
*
* Bike park-and-ride and "OV-fiets mode" development has been funded by GoAbout
* (https://goabout.com/).
*
* @author laurent
* @author GoAbout
*/
public class BikeParkEdge extends Edge {
private static final long serialVersionUID = 1L;
public BikeParkEdge(BikeParkVertex bikeParkVertex) {
super(bikeParkVertex, bikeParkVertex);
}
@Override
public State traverse(State s0) {
RoutingRequest options = s0.getOptions();
if (options.arriveBy) {
return traverseUnpark(s0);
} else {
return traversePark(s0);
}
}
protected State traverseUnpark(State s0) {
RoutingRequest options = s0.getOptions();
/*
* To unpark a bike, we need to be walking, and be allowed to bike.
*/
if (s0.getNonTransitMode() != TraverseMode.WALK || !options.modes.getBicycle())
return null;
StateEditor s0e = s0.edit(this);
s0e.incrementWeight(options.bikeParkCost);
s0e.incrementTimeInSeconds(options.bikeParkTime);
s0e.setBackMode(TraverseMode.LEG_SWITCH);
s0e.setBikeParked(false);
State s1 = s0e.makeState();
return s1;
}
protected State traversePark(State s0) {
RoutingRequest options = s0.getOptions();
/*
* To park a bike, we need to be riding one, (not rented) and be allowed to walk and to park
* it.
*/
if (s0.getNonTransitMode() != TraverseMode.BICYCLE || !options.modes.getWalk()
|| s0.isBikeRenting() || s0.isBikeParked())
return null;
BikeParkVertex bikeParkVertex = (BikeParkVertex) tov;
if (bikeParkVertex.getSpacesAvailable() == 0) {
return null;
}
StateEditor s0e = s0.edit(this);
s0e.incrementWeight(options.bikeParkCost);
s0e.incrementTimeInSeconds(options.bikeParkTime);
s0e.setBackMode(TraverseMode.LEG_SWITCH);
s0e.setBikeParked(true);
State s1 = s0e.makeState();
return s1;
}
@Override
public double getDistance() {
return 0;
}
@Override
public LineString getGeometry() {
return null;
}
@Override
public String getName() {
return getToVertex().getName();
}
@Override
public String getName(Locale locale) {
return getToVertex().getName(locale);
}
@Override
public boolean hasBogusName() {
return false;
}
public boolean equals(Object o) {
if (o instanceof BikeParkEdge) {
BikeParkEdge other = (BikeParkEdge) o;
return other.getFromVertex().equals(fromv) && other.getToVertex().equals(tov);
}
return false;
}
public String toString() {
return "BikeParkEdge(" + fromv + " -> " + tov + ")";
}
}