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

com.graphhopper.routing.Path Maven / Gradle / Ivy

Go to download

GraphHopper is a fast and memory efficient Java road routing engine working seamlessly with OpenStreetMap data.

There is a newer version: 10.0
Show newest version
/*
 *  Licensed to GraphHopper GmbH under one or more contributor
 *  license agreements. See the NOTICE file distributed with this work for
 *  additional information regarding copyright ownership.
 *
 *  GraphHopper GmbH licenses this file to you under the Apache License,
 *  Version 2.0 (the "License"); you may not use this file except in
 *  compliance with the License. You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.graphhopper.routing;

import com.carrotsearch.hppc.IntArrayList;
import com.carrotsearch.hppc.IntIndexedContainer;
import com.graphhopper.storage.Graph;
import com.graphhopper.storage.NodeAccess;
import com.graphhopper.util.EdgeIterator;
import com.graphhopper.util.EdgeIteratorState;
import com.graphhopper.util.FetchMode;
import com.graphhopper.util.PointList;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * This class represents the result of a shortest path calculation. It also provides methods to extract further
 * information about the found path, like instructions etc.
 *
 * @author Peter Karich
 * @author Ottavio Campana
 * @author jan soe
 * @author easbar
 */
public class Path {
    final Graph graph;
    private final NodeAccess nodeAccess;
    private double weight = Double.MAX_VALUE;
    private double distance;
    private long time;
    private IntArrayList edgeIds = new IntArrayList();
    private int fromNode = -1;
    private int endNode = -1;
    private List description;
    private boolean found;
    private String debugInfo = "";

    public Path(Graph graph) {
        this.graph = graph;
        this.nodeAccess = graph.getNodeAccess();
    }

    public Graph getGraph() {
        return graph;
    }

    /**
     * @return the description of this route alternative to make it meaningful for the user e.g. it
     * displays one or two main roads of the route.
     */
    public List getDescription() {
        if (description == null)
            return Collections.emptyList();
        return description;
    }

    public Path setDescription(List description) {
        this.description = description;
        return this;
    }

    public IntArrayList getEdges() {
        return edgeIds;
    }

    public void setEdges(IntArrayList edgeIds) {
        this.edgeIds = edgeIds;
    }

    public void addEdge(int edge) {
        edgeIds.add(edge);
    }

    public int getEdgeCount() {
        return edgeIds.size();
    }

    public int getEndNode() {
        return endNode;
    }

    public Path setEndNode(int end) {
        endNode = end;
        return this;
    }

    /**
     * @return the first node of this Path.
     */
    private int getFromNode() {
        if (fromNode < 0)
            throw new IllegalStateException("fromNode < 0 should not happen");

        return fromNode;
    }

    /**
     * We need to remember fromNode explicitly as its not saved in one edgeId of edgeIds.
     */
    public Path setFromNode(int from) {
        fromNode = from;
        return this;
    }

    public boolean isFound() {
        return found;
    }

    public Path setFound(boolean found) {
        this.found = found;
        return this;
    }

    public Path setDistance(double distance) {
        this.distance = distance;
        return this;
    }

    public Path addDistance(double distance) {
        this.distance += distance;
        return this;
    }

    /**
     * @return distance in meter
     */
    public double getDistance() {
        return distance;
    }

    /**
     * @return time in millis
     */
    public long getTime() {
        return time;
    }

    public Path setTime(long time) {
        this.time = time;
        return this;
    }

    public Path addTime(long time) {
        this.time += time;
        return this;
    }

    /**
     * This weight will be updated during the algorithm. The initial value is maximum double.
     */
    public double getWeight() {
        return weight;
    }

    public Path setWeight(double w) {
        this.weight = w;
        return this;
    }

    /**
     * Yields the final edge of the path
     */
    public EdgeIteratorState getFinalEdge() {
        return graph.getEdgeIteratorState(edgeIds.get(edgeIds.size() - 1), endNode);
    }

    public void setDebugInfo(String debugInfo) {
        this.debugInfo = debugInfo;
    }

    public String getDebugInfo() {
        return debugInfo;
    }

    /**
     * Iterates over all edges in this path sorted from start to end and calls the visitor callback
     * for every edge.
     * 

* * @param visitor callback to handle every edge. The edge is decoupled from the iterator and can * be stored. */ public void forEveryEdge(EdgeVisitor visitor) { int tmpNode = getFromNode(); int len = edgeIds.size(); int prevEdgeId = EdgeIterator.NO_EDGE; for (int i = 0; i < len; i++) { EdgeIteratorState edgeBase = graph.getEdgeIteratorState(edgeIds.get(i), tmpNode); if (edgeBase == null) throw new IllegalStateException("Edge " + edgeIds.get(i) + " was empty when requested with node " + tmpNode + ", array index:" + i + ", edges:" + edgeIds.size()); tmpNode = edgeBase.getBaseNode(); // more efficient swap, currently not implemented for virtual edges: visitor.next(edgeBase.detach(true), i); edgeBase = graph.getEdgeIteratorState(edgeBase.getEdge(), tmpNode); visitor.next(edgeBase, i, prevEdgeId); prevEdgeId = edgeBase.getEdge(); } visitor.finish(); } /** * Returns the list of all edges. */ public List calcEdges() { final List edges = new ArrayList<>(edgeIds.size()); if (edgeIds.isEmpty()) return edges; forEveryEdge(new EdgeVisitor() { @Override public void next(EdgeIteratorState eb, int index, int prevEdgeId) { edges.add(eb); } @Override public void finish() { } }); return edges; } /** * @return the uncached node indices of the tower nodes in this path. */ public IntIndexedContainer calcNodes() { final IntArrayList nodes = new IntArrayList(edgeIds.size() + 1); if (edgeIds.isEmpty()) { if (isFound()) { nodes.add(endNode); } return nodes; } int tmpNode = getFromNode(); nodes.add(tmpNode); forEveryEdge(new EdgeVisitor() { @Override public void next(EdgeIteratorState eb, int index, int prevEdgeId) { nodes.add(eb.getAdjNode()); } @Override public void finish() { } }); return nodes; } /** * This method calculated a list of points for this path *

* * @return the geometry of this path */ public PointList calcPoints() { final PointList points = new PointList(edgeIds.size() + 1, nodeAccess.is3D()); if (edgeIds.isEmpty()) { if (isFound()) { points.add(nodeAccess, endNode); } return points; } int tmpNode = getFromNode(); points.add(nodeAccess, tmpNode); forEveryEdge(new EdgeVisitor() { @Override public void next(EdgeIteratorState eb, int index, int prevEdgeId) { PointList pl = eb.fetchWayGeometry(FetchMode.PILLAR_AND_ADJ); for (int j = 0; j < pl.size(); j++) { points.add(pl, j); } } @Override public void finish() { } }); return points; } @Override public String toString() { return "found: " + found + ", weight: " + weight + ", time: " + time + ", distance: " + distance + ", edges: " + edgeIds.size(); } /** * The callback used in forEveryEdge. */ public interface EdgeVisitor { void next(EdgeIteratorState edge, int index, int prevEdgeId); void finish(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy