Construire des itinéraires ..., les gens l'utilisent régulièrement, notamment pour les itinéraires automobiles, dans les navigateurs.
Il existe également de nombreuses solutions pour construire un itinéraire, dont GraphHopper , qui sait construire des itinéraires pour les voitures, et pour les piétons, et même pour la randonnée, ce qui convient probablement dans 99% des cas.
Ensuite, nous parlerons de ce qu'il faut faire dans d'autres situations, plus précisément de mon expérience d'utilisation de GraphHopper lorsque la solution existante ne correspondait pas. Il était nécessaire de prendre en compte des restrictions supplémentaires: construire des itinéraires pédestres pour les personnes handicapées. Il n'y aura pas de caractéristiques significatives de la mise en œuvre de cette tâche particulière. Généralisée.
Il décrira comment créer votre propre service Web basé sur la bibliothèque GraphHopper, qui, en fonction des coordonnées du début et de la fin du chemin, renverra un tableau de coordonnées d'itinéraire.
Un exemple d'application, avec tous les stubs dont vous avez besoin pour exécuter, peut être trouvé dans mon référentiel sur GitHub .
GraphHopper est un moteur de routage écrit en Java. Publié sous la licence Apache, et peut être intégré dans des produits à code source fermé.
On trouve des articles de ce genre sur Habré, par exemple, Se promener sagement dans la ville , mais ça ne donne pas de détails de mise en œuvre, malheureusement, et ... enfin, c'est tout.
Également dans la publication Nouvelles du monde d'OpenStreetMap n ° 512 (05/05/2020 - 05/11/2020) , il y avait des nouvelles du contenu suivant:
Les développeurs de GraphHopper attendent nos commentaires, car ils ont introduit une nouvelle fonctionnalité qui permet même aux personnes sans programmation ni connaissances Java de modifier le modèle de construction d'itinéraire.
Probablement, cette nouvelle fonction couvrira 0,99% des situations possibles, elle conviendra probablement aussi à votre tâche, la connaissance de Java n'est pas requise et aucun problème ne se posera. Je vais vous parler de mon expérience dans la création de règles de construction d'itinéraires, lorsque cette fonction n'était pas là, et qu'il restait 2 ans avant sa création.
La connaissance de Java est requise.
, , :
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
, , .
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;
}
Si vous en avez l'occasion, pour votre tâche, utilisez la deuxième option, basée sur la vérification des balises - il vaut mieux la préférer. Cela ne fait pas de mal de mélanger une logique supplémentaire qui ne rentre pas dans cette approche.
Bonne chance!