org.openlr.encoder.PointAlongLineEncoder Maven / Gradle / Ivy
The newest version!
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 org.openlr.map.PointAlongLine;
import java.util.List;
class PointAlongLineEncoder {
private final MapOperations mapOperations;
private final PathSplitter pathSplitter;
private final LocationReferencePointCreator locationReferencePointCreator;
PointAlongLineEncoder(MapOperations mapOperations, PathSplitter pathSplitter, LocationReferencePointCreator locationReferencePointCreator) {
this.mapOperations = mapOperations;
this.pathSplitter = pathSplitter;
this.locationReferencePointCreator = locationReferencePointCreator;
}
> PointAlongLineEncoderResult encode(PointAlongLine pointAlongLine) {
Path backwardExpansion = mapOperations.expandToValidNode(pointAlongLine, false);
Path forwardExpansion = mapOperations.expandToValidNode(pointAlongLine, true);
Path expandedPath = mapOperations.joinPaths(List.of(
backwardExpansion,
forwardExpansion));
List> subPaths = pathSplitter.split(expandedPath);
double distanceToPoint = backwardExpansion.getLength();
double distance = 0;
Path relevantSubPath = null;
double relativePositiveOffset = 0;
for (Path subPath : subPaths) {
double nextDistance = distance + subPath.getLength();
if (distance <= distanceToPoint && nextDistance > distanceToPoint) {
relevantSubPath = subPath;
relativePositiveOffset = (distanceToPoint - distance) / subPath.getLength();
break;
}
}
if (relevantSubPath == null) {
throw new IllegalStateException();
}
LocationReferencePoint firstLocationReferencePoint = locationReferencePointCreator.create(relevantSubPath.getStart(), relevantSubPath);
LocationReferencePoint lastLocationReferencePoint = locationReferencePointCreator.create(relevantSubPath.getEnd());
return new PointAlongLineEncoderResult(
firstLocationReferencePoint,
lastLocationReferencePoint,
relativePositiveOffset);
}
}