Como usar o GraphHopper para construir seus próprios percursos pedestres

Construindo rotas ..., as pessoas usam regularmente, especialmente para rotas de carro, em navegadores.





Existem também muitas soluções para a construção de um percurso, incluindo o GraphHopper , que sabe construir percursos para automóveis, para peões e até para caminhadas, o que provavelmente é adequado em 99% dos casos.





A seguir, falaremos sobre o que fazer em outras situações, mais precisamente sobre minha experiência de usar o GraphHopper quando a solução existente não se encaixava. Era preciso levar em conta restrições adicionais: construir percursos pedonais para pessoas com deficiência. Não haverá características significativas da implementação desta tarefa específica. Generalizado.





Ele descreverá como criar seu próprio serviço web com base na biblioteca GraphHopper, que, com base nas coordenadas de início e fim do caminho, retornará uma matriz de coordenadas de rota.





Um aplicativo de amostra, com todos os stubs que você precisa para executar, pode ser encontrado em meu repositório no GitHub .





GraphHopper é um mecanismo de roteamento escrito em Java. Distribuído sob a licença Apache e pode ser incorporado em produtos de código fechado.





Artigos desse tipo no Habré são encontrados, por exemplo, Walking around the city sabiamente , mas não fornece detalhes de implementação, infelizmente, e ... bem, é isso.





Ainda na publicação Notícias do mundo do OpenStreetMap nº 512 (05/05/2020 - 05/11/2020) , surgiram notícias com o seguinte conteúdo:





Os desenvolvedores do GraphHopper estão aguardando nossos comentários, pois eles introduziram um novo recurso que permite que até mesmo pessoas sem programação ou conhecimento de Java alterem o modelo de construção de rota.





Provavelmente, esta nova função abrangerá outros 0,99% das situações possíveis, provavelmente será adequada para a sua tarefa também, não é necessário conhecimento de Java e nenhum problema surgirá. Contarei a vocês minha experiência na criação de regras para construção de rotas, quando esta função não existia e faltavam 2 anos para sua criação.





É necessário conhecimento de Java.





, , :









  • GraphHopper OSM, , OSM. , , OSM. . , .





GraphHopper 0.10.0, .





.





Maven:





<dependency>
	<groupId>com.graphhopper</groupId>
	<artifactId>graphhopper-reader-osm</artifactId>
	<version>0.10.0</version>
</dependency> 
      
      



GraphHopper, , github. , How to create new routing profile aka a new FlagEncoder? , , FlagEncoder



. FlagEncoder



, com.graphhopper.routing.util



, FootFlagEncoder



, .. , AbstractFlagEncoder



, .





GraphHopper ( ) GraphHopper Documentation RoutingExample.java.





FlagEncoder

, FlagEncoder



AbstractFlagEncoder



, FootFlagEncoder



, FootFlagEncoder



, . AbstractFlagEncoder



FootFlagEncoder



, , FootFlagEncoder



.





acceptWay



, - ReaderWay



/ . FlagEncoder



. FlagEncoder



, . acceptWay



, – 0.





restricted



, id



way



OSM.





public class MyFlagEncoder {

	
	private List<Long> restricted;
	
	@Override
	public long acceptWay(ReaderWay way) {
        if (restricted.contains(way.getId()))
            return 0;
	}
	
	
}
      
      



, , , 0.





FlagEncoder



, , .





Routing via Java API.





GraphHopper closableInstance = new GraphHopperOSM().setOSMFile(osmFilePath).forServer();
closableInstance.setStoreOnFlush(true);
closableInstance.setGraphHopperLocation(graphFolder);
closableInstance.setEncodingManager(new EncodingManager(encoder));
closableInstance.setCHEnabled(false);

GraphHopper hopper = closableInstance.importOrLoad();
      
      







  • osmFilePath - pbf- , pbf geofabrik, , OSM;





  • encoder – FlagEncoder



    , , ;





  • graphFolder – .





importOrLoad



, FlagEncoder



, .





GraphHopper: Low level API.





importOrLoad



.





GraphHopper closableInstance = new GraphHopperOSM().
	setOSMFile(pbfFile).
	forServer().
	setStoreOnFlush(true).
	setGraphHopperLocation(graphFolder).
	setEncodingManager(new EncodingManager(encoder)).
	setCHEnabled(false);
GraphHopper hopper = closableInstance.importOrLoad();
      
      



LocationIndex



:





GraphHopperStorage graph = hopper.getGraphHopperStorage();
LocationIndex index = new LocationIndexTree(graph, new RAMDirectory());
index.prepareIndex();
      
      



: GraphHopperStorage



, FlagEncoder



, LocationIndex



.





, List<Double[]>



:





QueryResult fromQR = index.findClosest(fromLon, fromLat, EdgeFilter.ALL_EDGES);
QueryResult toQR = index.findClosest(toLon, toLat, EdgeFilter.ALL_EDGES);

QueryGraph queryGraph = new QueryGraph(graph);

//   
queryGraph.lookup(fromQR, toQR);
Dijkstra dij = new Dijkstra(queryGraph, new FastestWeighting(encoder), TraversalMode.NODE_BASED);
Path path = dij.calcPath(fromQR.getClosestNode(), toQR.getClosestNode());

PointList pl = path.calcPoints();
return pl.toGeoJson();
      
      



.. ( acceptWay



) ( ) :





if (restricted.contains(way.getId()))
	return 0;
      
      



- , OSM, :





if (way.hasTag("foot", intendedValues)) {
	return acceptBit;
}
      
      



Se você tiver oportunidade, para a sua tarefa, use a segunda opção, baseada na verificação de tags - é melhor preferir. Isso não atrapalha misturar lógica adicional que não se encaixa nessa abordagem.





Boa sorte!








All Articles