org.openlr.encoder.PathEncoder Maven / Gradle / Ivy
package org.openlr.encoder;
import org.openlr.locationreference.LocationReferencePoint;
import org.openlr.map.Line;
import org.openlr.map.MapOperations;
import org.openlr.map.Path;
import java.util.ArrayList;
import java.util.List;
class PathEncoder {
private final MapOperations mapOperations;
private final PathSplitter pathSplitter;
private final LocationReferencePointCreator locationReferencePointCreator;
PathEncoder(MapOperations mapOperations, PathSplitter pathSplitter, LocationReferencePointCreator locationReferencePointCreator) {
this.mapOperations = mapOperations;
this.pathSplitter = pathSplitter;
this.locationReferencePointCreator = locationReferencePointCreator;
}
> PathEncoderResult encode(Path path) {
Path backwardExpansion = mapOperations.expandToValidNode(path.getStart(), false);
Path forwardExpansion = mapOperations.expandToValidNode(path.getEnd(), true);
Path expandedPath = mapOperations.joinPaths(List.of(
backwardExpansion,
path,
forwardExpansion));
List> subPaths = pathSplitter.split(expandedPath);
double distanceToStart = backwardExpansion.getLength();
double distanceToEnd = backwardExpansion.getLength() + path.getLength();
double distance = 0;
List> subPathsAlongPath = new ArrayList<>();
double relativePositiveOffset = 0;
double relativeNegativeOffset = 0;
for (Path subPath : subPaths) {
double nextDistance = distance + subPath.getLength();
if (distance < distanceToEnd && nextDistance > distanceToStart) {
subPathsAlongPath.add(subPath);
}
if (distance < distanceToStart && nextDistance > distanceToStart) {
relativePositiveOffset = (distanceToStart - distance) / subPath.getLength();
}
if (distance < distanceToEnd && nextDistance > distanceToEnd) {
relativeNegativeOffset = (nextDistance - distanceToEnd) / subPath.getLength();
}
}
List locationReferencePoints = new ArrayList<>();
for (Path subPath : subPathsAlongPath) {
LocationReferencePoint locationReferencePoint = locationReferencePointCreator.create(subPath.getStart(), subPath);
locationReferencePoints.add(locationReferencePoint);
}
Path lastSubPath = subPathsAlongPath.get(subPathsAlongPath.size() - 1);
LocationReferencePoint lastLocationReferencePoint = locationReferencePointCreator.create(lastSubPath.getEnd());
locationReferencePoints.add(lastLocationReferencePoint);
return new PathEncoderResult(
locationReferencePoints,
relativePositiveOffset,
relativeNegativeOffset);
}
}