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

com.graphhopper.gtfs.PtLocationSnapper Maven / Gradle / Ivy

There is a newer version: 10.0
Show newest version
package com.graphhopper.gtfs;

import com.carrotsearch.hppc.IntHashSet;
import com.carrotsearch.hppc.cursors.IntCursor;
import com.conveyal.gtfs.GTFSFeed;
import com.conveyal.gtfs.model.Stop;
import com.graphhopper.routing.querygraph.QueryGraph;
import com.graphhopper.routing.util.EdgeFilter;
import com.graphhopper.storage.BaseGraph;
import com.graphhopper.storage.index.LocationIndex;
import com.graphhopper.storage.index.Snap;
import com.graphhopper.util.PointList;
import com.graphhopper.util.exceptions.PointNotFoundException;
import com.graphhopper.util.shapes.GHPoint;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;

public class PtLocationSnapper {

    public static class Result {
        public final QueryGraph queryGraph;
        public final List nodes;
        public final PointList points;

        public Result(QueryGraph queryGraph, List nodes, PointList points) {
            this.queryGraph = queryGraph;
            this.nodes = nodes;
            this.points = points;
        }
    }

    BaseGraph baseGraph;
    LocationIndex locationIndex;
    GtfsStorage gtfsStorage;

    public PtLocationSnapper(BaseGraph baseGraph, LocationIndex locationIndex, GtfsStorage gtfsStorage) {
        this.baseGraph = baseGraph;
        this.locationIndex = locationIndex;
        this.gtfsStorage = gtfsStorage;
    }

    public Result snapAll(List locations, List snapFilters) {
        PointList points = new PointList(2, false);
        ArrayList pointSnaps = new ArrayList<>();
        ArrayList> allSnaps = new ArrayList<>();
        for (int i = 0; i < locations.size(); i++) {
            GHLocation location = locations.get(i);
            if (location instanceof GHPointLocation) {
                GHPoint point = ((GHPointLocation) location).ghPoint;
                final Snap closest = locationIndex.findClosest(point.lat, point.lon, snapFilters.get(i));
                if (!closest.isValid()) {
                    IntHashSet result = new IntHashSet();
                    gtfsStorage.getStopIndex().findEdgeIdsInNeighborhood(point.lat, point.lon, 0, result::add);
                    gtfsStorage.getStopIndex().findEdgeIdsInNeighborhood(point.lat, point.lon, 1, result::add);
                    if (result.isEmpty()) {
                        throw new PointNotFoundException("Cannot find point: " + point, i);
                    }
                    IntCursor stopNodeId = result.iterator().next();
                    for (Map.Entry e : gtfsStorage.getStationNodes().entrySet()) {
                        if (e.getValue() == stopNodeId.value) {
                            Stop stop = gtfsStorage.getGtfsFeeds().get(e.getKey().feedId).stops.get(e.getKey().stopId);
                            final Snap stopSnap = new Snap(stop.stop_lat, stop.stop_lon);
                            stopSnap.setClosestNode(stopNodeId.value);
                            allSnaps.add(() -> new Label.NodeId(gtfsStorage.getPtToStreet().getOrDefault(stopSnap.getClosestNode(), -1), stopSnap.getClosestNode()));
                            points.add(stopSnap.getQueryPoint().lat, stopSnap.getQueryPoint().lon);
                        }
                    }
                } else {
                    pointSnaps.add(closest);
                    allSnaps.add(() -> new Label.NodeId(closest.getClosestNode(), gtfsStorage.getStreetToPt().getOrDefault(closest.getClosestNode(), -1)));
                    points.add(closest.getSnappedPoint());
                }
            } else if (location instanceof GHStationLocation) {
                final Snap stopSnap = findByStopId((GHStationLocation) location, i);
                allSnaps.add(() -> new Label.NodeId(gtfsStorage.getPtToStreet().getOrDefault(stopSnap.getClosestNode(), -1), stopSnap.getClosestNode()));
                points.add(stopSnap.getQueryPoint().lat, stopSnap.getQueryPoint().lon);
            }
        }
        QueryGraph queryGraph = QueryGraph.create(baseGraph.getBaseGraph(), pointSnaps); // modifies pointSnaps!

        List nodes = new ArrayList<>();
        for (Supplier supplier : allSnaps) {
            nodes.add(supplier.get());
        }
        return new Result(queryGraph, nodes, points);
    }

    private Snap findByStopId(GHStationLocation station, int indexForErrorMessage) {
        for (Map.Entry entry : gtfsStorage.getGtfsFeeds().entrySet()) {
            final Integer node = gtfsStorage.getStationNodes().get(new GtfsStorage.FeedIdWithStopId(entry.getKey(), station.stop_id));
            if (node != null) {
                Stop stop = gtfsStorage.getGtfsFeeds().get(entry.getKey()).stops.get(station.stop_id);
                final Snap stationSnap = new Snap(stop.stop_lat, stop.stop_lon);
                stationSnap.setClosestNode(node);
                return stationSnap;
            }
        }
        throw new PointNotFoundException("Cannot find station: " + station.stop_id, indexForErrorMessage);
    }


}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy