package pl.edu.agh.logic;
import static com.google.common.collect.Lists.newArrayList;
import static pl.edu.agh.spatial.HaversineDistanceCalculator.EARTH_DISTANCE_CALCULATOR;
import java.util.List;
import pl.edu.agh.model.Way;
import pl.edu.agh.spatial.LineSegmentList;
import com.google.common.collect.Lists;
import com.vividsolutions.jts.geom.LineSegment;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.Point;
public abstract class WayWithOneEndPoint extends WayWithEndPoints {
protected Point point;
public WayWithOneEndPoint(Way way, Point point) {
super(way, point.getFactory());
this.point = point;
}
protected Integer getNearerVertexNumber() {
return EARTH_DISTANCE_CALCULATOR.distance(way.getStartPoint(), point) < EARTH_DISTANCE_CALCULATOR.distance(
way.getEndPoint(), point) ? way.getSource() : way.getTarget();
}
public abstract Integer getWayEndPoint();
public Integer getWayEndPointOppositeTo(Integer endPoint) {
if (endPoint.equals(way.getSource())) {
return way.getTarget();
} else if (endPoint.equals(way.getTarget())) {
return way.getSource();
} else {
throw new IllegalArgumentException("Passed endPoint is neither start nor end of way");
}
}
public List<Point> createRouteFromIndexToPoint(Integer index) {
if (way.getSource().equals(index)) {
return createWayFromSource();
} else if (way.getTarget().equals(index)) {
return createWayFromTarget();
} else
throw new IllegalArgumentException("Passed index is neither start nor end of way");
}
public List<Point> createRouteFromPointToIndex(Integer index) {
return Lists.reverse(createRouteFromIndexToPoint(index));
}
private List<Point> createWayFromTarget() {
return createWayFromPoint(new LineSegmentList((LineString) way.getLineString().reverse()));
}
private List<Point> createWayFromSource() {
return createWayFromPoint(new LineSegmentList(way.getLineString()));
}
private List<Point> createWayFromPoint(LineSegmentList lines) {
LineSegment nearestLine = lines.nearestLine(point);
List<Point> route = newArrayList();
for (LineSegment line : lines) {
route.add(geometryFactory.createPoint(line.p0));
if (line.equals(nearestLine)) {
break;
}
}
route.add(geometryFactory.createPoint(nearestLine.closestPoint(point.getCoordinate())));
return route;
}
}