* very close to one of the existing endpoints. Returns the vertices located at the split point.
*/
private Collection<StreetVertex> split(LinkedList<P2<StreetEdge>> replacement, String label,
P2<StreetEdge> bestPair, Coordinate coordinate) {
StreetEdge e1 = bestPair.first;
StreetEdge e2 = bestPair.second;
String name = e1.getName();
StreetVertex e1v1 = (StreetVertex) e1.getFromVertex();
StreetVertex e1v2 = (StreetVertex) e1.getToVertex();
LineString forwardGeometry = e1.getGeometry();
StreetVertex e2v1 = null;
StreetVertex e2v2 = null;
P2<LineString> backGeometryPair = null;
if (e2 != null) {
e2v1 = (StreetVertex) e2.getFromVertex();
e2v2 = (StreetVertex) e2.getToVertex();
LineString backGeometry = e2.getGeometry();
backGeometryPair = GeometryUtils.splitGeometryAtPoint(backGeometry,
coordinate);
}
P2<LineString> forwardGeometryPair = GeometryUtils.splitGeometryAtPoint(forwardGeometry,
coordinate);
LineString forward1Geom = forwardGeometryPair.first;
LineString forward2Geom = forwardGeometryPair.second;
Coordinate midCoord = forward1Geom.getEndPoint().getCoordinate();
// determine how far along the original pair the split would occur
double totalGeomLength = forwardGeometry.getLength();
double lengthRatioIn = forward1Geom.getLength() / totalGeomLength;
// If coordinate is coincident with an endpoint of the edge pair, splitting is unnecessary.
// note: the pair potentially being split was generated by the 'replace' method,
// so the two PlainStreetEdges are known to be pointing in opposite directions.
if (lengthRatioIn < 0.00001) {
ArrayList<StreetVertex> out = new ArrayList<StreetVertex>();
out.add(e1v1);
if (e2 != null) {
out.add(e2v2);
}
return out;
} else if (lengthRatioIn > 0.99999) {
ArrayList<StreetVertex> out = new ArrayList<StreetVertex>();
out.add(e1v2);
if (e2 != null) {
out.add(e1v2);
}
return out;
}
double lengthIn = e1.getDistance() * lengthRatioIn;
double lengthOut = e1.getDistance() * (1 - lengthRatioIn);
// Split each edge independently. If a only one splitter vertex is used, routing may take
// shortcuts thought the splitter vertex to avoid turn penalties.
IntersectionVertex e1midpoint = new IntersectionVertex(linker.graph, "split 1 at " + label, midCoord.x, midCoord.y, name);
// We are replacing two edges with four edges
// Note: Always enable elevation. This should not be a big waste of memory.
StreetWithElevationEdge forward1 = new StreetWithElevationEdge(e1v1, e1midpoint, forward1Geom, name, lengthIn,
e1.getPermission(), e1.isBack());
StreetWithElevationEdge forward2 = new StreetWithElevationEdge(e1midpoint, e1v2, forward2Geom, name, lengthOut,
e1.getPermission(), e1.isBack());
if (e1 instanceof AreaEdge) {
((AreaEdge) e1).getArea().addVertex(e1midpoint, linker.graph);
}
addEdges(forward1, forward2);
StreetWithElevationEdge backward1 = null;
StreetWithElevationEdge backward2 = null;
IntersectionVertex e2midpoint = null;
if (e2 != null) {
e2midpoint = new IntersectionVertex(linker.graph, "split 2 at " + label, midCoord.x, midCoord.y, name);
backward1 = new StreetWithElevationEdge(e2v1, e2midpoint, backGeometryPair.first,
name, lengthOut, e2.getPermission(), e2.isBack());
backward2 = new StreetWithElevationEdge(e2midpoint, e2v2, backGeometryPair.second,
name, lengthIn, e2.getPermission(), e2.isBack());
if (e2 instanceof AreaEdge) {
((AreaEdge) e2).getArea().addVertex(e2midpoint, linker.graph);
}
backward1.setBicycleSafetyFactor(e2.getBicycleSafetyFactor());
backward2.setBicycleSafetyFactor(e2.getBicycleSafetyFactor());
backward1.setElevationProfile(ElevationUtils.getPartialElevationProfile(
e2.getElevationProfile(), 0, lengthOut), false);
backward2.setElevationProfile(ElevationUtils.getPartialElevationProfile(
e2.getElevationProfile(), lengthIn, totalGeomLength), false);
backward1.setHasBogusName(e2.hasBogusName());
backward2.setHasBogusName(e2.hasBogusName());
backward1.setStairs(e2.isStairs());
backward2.setStairs(e2.isStairs());
backward1.setWheelchairAccessible(e2.isWheelchairAccessible());
backward2.setWheelchairAccessible(e2.isWheelchairAccessible());
addEdges(backward1, backward2);
}
forward1.setBicycleSafetyFactor(e1.getBicycleSafetyFactor());
forward2.setBicycleSafetyFactor(e1.getBicycleSafetyFactor());