org.opentripplanner.routing.graph.Edge Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of otp Show documentation
Show all versions of otp Show documentation
The OpenTripPlanner multimodal journey planning system
/* 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 . */
package org.opentripplanner.routing.graph;
import com.vividsolutions.jts.geom.LineString;
import org.onebusaway.gtfs.model.Trip;
import org.opentripplanner.common.MavenVersion;
import org.opentripplanner.routing.core.RoutingRequest;
import org.opentripplanner.routing.core.State;
import org.opentripplanner.routing.util.IncrementingIdGenerator;
import org.opentripplanner.routing.util.UniqueIdGenerator;
import javax.xml.bind.annotation.XmlTransient;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Locale;
/**
* This is the standard implementation of an edge with fixed from and to Vertex instances;
* all standard OTP edges are subclasses of this.
*/
public abstract class Edge implements Serializable {
private static final long serialVersionUID = MavenVersion.VERSION.getUID();
/**
* Generates globally unique edge IDs.
*/
private static final UniqueIdGenerator idGenerator = new IncrementingIdGenerator();
/**
* Identifier of the edge. Negative means not set.
*/
private int id;
protected Vertex fromv;
protected Vertex tov;
protected Edge(Vertex v1, Vertex v2) {
if (v1 == null || v2 == null) {
String err = String.format("%s constructed with null vertex : %s %s", this.getClass(),
v1, v2);
throw new IllegalStateException(err);
}
this.fromv = v1;
this.tov = v2;
this.id = idGenerator.getId(this);
// if (! vertexTypesValid()) {
// throw new IllegalStateException(this.getClass() +
// " constructed with bad vertex types");
// }
fromv.addOutgoing(this);
tov.addIncoming(this);
}
public Vertex getFromVertex() {
return fromv;
}
public Vertex getToVertex() {
return tov;
}
/**
* Returns true if this edge is partial - overriden by subclasses.
*/
public boolean isPartial() {
return false;
}
/**
* Checks equivalency to another edge. Default implementation is trivial equality, but subclasses may want to do something more tricky.
*/
public boolean isEquivalentTo(Edge e) {
return this == e;
}
/**
* Returns true if this edge is the reverse of another.
*/
public boolean isReverseOf(Edge e) {
return (this.getFromVertex() == e.getToVertex() &&
this.getToVertex() == e.getFromVertex());
}
/**
* Get a direction on paths where it matters, or null
*
* @return
*/
public String getDirection() {
return null;
}
/**
* This should only be called inside State; other methods should call
* org.opentripplanner.routing.core.State.getBackTrip()
*
* @author mattwigway
*/
public Trip getTrip() {
return null;
}
// Notes are now handled by State
@Override
public int hashCode() {
return fromv.hashCode() * 31 + tov.hashCode();
}
/**
* Edges are not roundabouts by default.
*/
public boolean isRoundabout() {
return false;
}
/**
* Traverse this edge.
*
* @param s0 The State coming into the edge.
* @return The State upon exiting the edge.
*/
public abstract State traverse(State s0);
public State optimisticTraverse(State s0) {
return this.traverse(s0);
}
/**
* Returns a lower bound on edge weight given the routing options.
*
* @param options
* @return edge weight as a double.
*/
public double weightLowerBound(RoutingRequest options) {
// Edge weights are non-negative. Zero is an admissible default lower
// bound.
return 0;
}
/**
* Returns a lower bound on traversal time given the routing options.
*
* @param options
* @return edge weight as a double.
*/
public double timeLowerBound(RoutingRequest options) {
// No edge should take less than zero time to traverse.
return 0;
}
/**
* Gets english localized name
* @return english localized name
*/
public abstract String getName();
/**
* Gets wanted localization
* @param locale wanted locale
* @return Localized in specified locale name
*/
public abstract String getName(Locale locale);
// TODO Add comments about what a "bogus name" is.
public boolean hasBogusName() {
return false;
}
public String toString() {
if (id >= 0) {
return String.format("%s:%s (%s -> %s)", getClass().getName(), id, fromv, tov);
}
return String.format("%s (%s -> %s)", getClass().getName(), fromv, tov);
}
// The next few functions used to live in EdgeNarrative, which has now been
// removed
// @author mattwigway
public LineString getGeometry() {
return null;
}
/**
* Returns the azimuth of this edge from head to tail.
*
* @return
*/
public double getAzimuth() {
// TODO(flamholz): cache?
return getFromVertex().azimuthTo(getToVertex());
}
public double getDistance() {
return 0;
}
/* SERIALIZATION */
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
// edge lists are transient, reconstruct them
fromv.addOutgoing(this);
tov.addIncoming(this);
}
private void writeObject(ObjectOutputStream out) throws IOException, ClassNotFoundException {
if (fromv == null) {
System.out.printf("fromv null %s \n", this);
}
if (tov == null) {
System.out.printf("tov null %s \n", this);
}
out.defaultWriteObject();
}
/* GRAPH COHERENCY AND TYPE CHECKING */
@SuppressWarnings("unchecked")
private static final ValidVertexTypes VALID_VERTEX_TYPES = new ValidVertexTypes(Vertex.class,
Vertex.class);
@XmlTransient
public ValidVertexTypes getValidVertexTypes() {
return VALID_VERTEX_TYPES;
}
/*
* This may not be necessary if edge constructor types are strictly specified
*/
public final boolean vertexTypesValid() {
return getValidVertexTypes().isValid(fromv, tov);
}
public static final class ValidVertexTypes {
private final Class extends Vertex>[] classes;
// varargs constructor:
// a loophole in the law against arrays/collections of parameterized
// generics
public ValidVertexTypes(Class extends Vertex>... classes) {
if (classes.length % 2 != 0) {
throw new IllegalStateException("from/to/from/to...");
} else {
this.classes = classes;
}
}
public boolean isValid(Vertex from, Vertex to) {
for (int i = 0; i < classes.length; i += 2) {
if (classes[i].isInstance(from) && classes[i + 1].isInstance(to))
return true;
}
return false;
}
}
public int getId(){
return this.id;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy