All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.openlr.encoder.PathEncoder Maven / Gradle / Ivy

There is a newer version: 2.0-beta3
Show 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 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);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy