package edu.kit.pse.ws2013.routekit.map;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import edu.kit.pse.ws2013.routekit.profiles.Profile;
/**
* This class encapsulates the properties of an edge.
*
* @see Graph
*/
public class EdgeProperties {
private final HighwayType type;
private final String name;
private final String roadRef;
private final int maxSpeed;
/**
* Creates a new {@code EdgeProperties} object with the given properties.
*
* @param type
* the highway type
* @param name
* the name of the street, or {@code null} if none
* @param roadRef
* the reference number of the road, or {@code null} if none
* @param maxSpeed
* the allowed maximum speed (in kilometers per hour), or
* {@code 0} if unspecified
* @throws IllegalArgumentException
* if {@code type} is {@code null} or {@code maxSpeed} is
* negative
*/
public EdgeProperties(HighwayType type, String name, String roadRef,
int maxSpeed) {
if (type == null || maxSpeed < 0) {
throw new IllegalArgumentException();
}
this.type = type;
this.name = name;
this.roadRef = roadRef;
this.maxSpeed = maxSpeed;
}
/**
* Returns the highway type of the edge.
*
* @return the highway type
*/
public HighwayType getType() {
return type;
}
/**
* Returns the street name of the edge.
*
* @return the street name, or {@code null} if none
*/
public String getName() {
return name;
}
/**
* Returns the road reference number of the edge.
*
* @return the road reference number, or {@code null} if none
*/
public String getRoadRef() {
return roadRef;
}
/**
* Calculates the allowed maximum speed of the edge for the specified
* profile.
*
* @param profile
* the profile in use
* @return the allowed maximum speed (in kilometers per hour)
*/
public int getMaxSpeed(Profile profile) {
int profileSpeed = (type == HighwayType.Motorway || type == HighwayType.Trunk) ? profile
.getSpeedHighway() : profile.getSpeedRoad();
if (maxSpeed == 0 || profileSpeed < maxSpeed) {
return profileSpeed;
}
return maxSpeed;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + maxSpeed;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((roadRef == null) ? 0 : roadRef.hashCode());
result = prime * result + ((type == null) ? 0 : type.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
EdgeProperties other = (EdgeProperties) obj;
if (maxSpeed != other.maxSpeed) {
return false;
}
if (name == null) {
if (other.name != null) {
return false;
}
} else if (!name.equals(other.name)) {
return false;
}
if (roadRef == null) {
if (other.roadRef != null) {
return false;
}
} else if (!roadRef.equals(other.roadRef)) {
return false;
}
if (type != other.type) {
return false;
}
return true;
}
/**
* Save this {@link EdgeProperties} object to the specified
* {@link DataOutput}; it can be loaded again by {@link #load(DataInput)}.
*
* <h4>Data format</h4>
*
* Pretty straightforward: {@link #getType() type.ordinal()},
* {@link #getName() name}, {@link #getRoadRef() roadRef} and
* {@link #getMaxSpeed(Profile) maxSpeed} are (in this order) written using
* {@link DataOutput#writeUTF(String)} and {@link DataOutput#writeInt(int)}.
*
* @param out
* The output.
* @throws IOException
* If an I/O error occurs.
*/
public void save(DataOutput out) throws IOException {
out.writeInt(type.ordinal());
out.writeUTF(name == null ? "" : name);
out.writeUTF(roadRef == null ? "" : roadRef);
out.writeInt(maxSpeed);
}
/**
* Load an {@link EdgeProperties} object from the specified
* {@link DataInput}. For the data format, see {@link #save(DataOutput)}.
*
* @param in
* The input.
* @return {@link EdgeProperties} parsed from {@code in}.
* @throws IOException
* If an I/O error occurs.
*/
public static EdgeProperties load(DataInput in) throws IOException {
final HighwayType type = HighwayType.values()[in.readInt()];
final String name = in.readUTF();
final String roadRef = in.readUTF();
final int maxSpeed = in.readInt();
return new EdgeProperties(type, name.isEmpty() ? null : name,
roadRef.isEmpty() ? null : roadRef, maxSpeed);
}
}