Как в Graphhopper получить набор ребер, содержащихся в маршруте?

В настоящее время я использую GraphHopper в приложении, которое определяет, проходит ли маршрут клиента мимо определенной точки интереса (PoI). Одна PoI имеет одну или несколько дорог, по которым может проехать клиент (заранее определено для каждой PoI).

Я думаю, что самый быстрый способ сделать это — найти каждый клиентский маршрут и посмотреть, включают ли ребра внутри маршрута какие-либо ребра, которые проходят PoI. Следующий код находит все ребра, ближайшие к точкам, хранящимся в объекте GHResponse (называемым «маршрутом» в приведенном ниже коде).

QueryResult qr;
HashMap<String, EdgeIteratorState> routeEdges= new HashMap<String, EdgeIteratorState>();
for(GHPoint p:route.getPoints()){
    qr = index.findClosest(p.getLat(), p.getLon(), EdgeFilter.ALL_EDGES );
    routeEdges.put(qr.getClosestEdge().toString(), qr.getClosestEdge());
}

Это использует конечные точки каждой дороги и ищет ближайшее ребро, которое я мог бы вернуть любому из ребер в этом узле. Я бы предпочел список edgeID внутри маршрута, чтобы вместо этого сравнивать их с ребрами для каждой PoI.

Любые советы будут высоко ценится. Ваше здоровье!


person Rob Anderson    schedule 17.04.2015    source источник
comment
Что означает «край»? Строка, содержащаяся в маршруте?   -  person Ubica    schedule 17.04.2015
comment
В настоящее время этот внутренний объект не доступен ни одному общедоступному методу в классе GraphHopper. Поэтому вам нужно будет использовать API более низкого уровня. Или вы можете перегрузить GraphHopper.getPaths и где-нибудь сохранить пути, а затем вызвать path.calcEdges   -  person Karussell    schedule 17.04.2015
comment
Ubica — ребро в GraphHopper (как я понимаю) — это двунаправленное ребро, которое соединяет два узла соединения/башни (могу ошибаться).   -  person Rob Anderson    schedule 20.04.2015
comment
Karussell - спасибо за подсказку. Ваш совет, похоже, работает хорошо, за исключением случаев, когда вы смотрите на начальную и конечную точки маршрута. Там, где начальная или конечная точка маршрута и PoI попадают между двумя узлами башни, кажется, что граница описывается по-разному и не обнаруживается. Есть ли у вас какие-либо советы по учету этого?   -  person Rob Anderson    schedule 20.04.2015
comment
GraphHopper создаст два виртуальных края, но с одним и тем же «исходным» краем, который можно использовать для их сопоставления. Вы можете получить «исходное» преимущество через QueryResult.getClosestEdge.   -  person Karussell    schedule 23.04.2015


Ответы (1)


Благодаря совету Karussell я создал свой собственный объект GraphHopper, который реализует определенный метод для возврата ребер, используемых в маршруте.

public class GraphHopperWithPaths extends GraphHopper {

public List<Integer> routePaths(double startY, double startX, double endY, double endX){

    //Examine a route and return edgeIDs that GraphHopper uses
    LocationIndex index = this.getLocationIndex();
    GHRequest request = new GHRequest(startY, startX, endY, endX);
    GHResponse response = new GHResponse();
    List<Path> paths = getPaths(request, response);
    List<Integer> edges = new ArrayList<Integer>();
    for(Path p:paths){
        for(EdgeIteratorState e:p.calcEdges()){
            edges.add(e.getEdge());
        }
    }
    if (response.hasErrors()) return null;

    //Get edges for start and end point as well
    QueryResult qr = index.findClosest(startY, startX, EdgeFilter.ALL_EDGES );
    edges.add(qr.getClosestEdge().getEdge());
    qr = index.findClosest(endY, endX, EdgeFilter.ALL_EDGES );
    edges.add(qr.getClosestEdge().getEdge());

    return edges;
}

}

Этот метод не возвращает сам маршрут, а это значит, что его следует изменить, если вам нужны и маршруты, и ребра. Выполнение обоих методов route и routePaths этого пользовательского объекта GraphHopper было бы неэффективным.

person Rob Anderson    schedule 01.05.2015