graphhopper / jsprit

jsprit is a java based, open source toolkit for solving rich vehicle routing problems
https://www.graphhopper.com/open-source/
Apache License 2.0
1.63k stars 604 forks source link

Jsprint and Google Map #523

Closed niocoders closed 2 years ago

niocoders commented 3 years ago

Hello, I want to integrate Google maps to calculate the actual distance in the city. Can you give me an idea, thank you

bludginozzie commented 3 years ago

You would need to implement your own VehicleRoutingTransportCosts

For example:

public class GoogleMapsVehicleRoutingTransportCosts extends AbstractForwardVehicleRoutingTransportCosts {

    @Override
    public double getDistance(Location from, Location to, double departureTime, Vehicle vehicle) {
        return callGoogleMapsDistanceApi(from, to, departureTime);
    }

    @Override
    public double getTransportTime(Location from, Location to, double departureTime, Driver driver, Vehicle vehicle) {
        return callGoogleMapsDistanceApi(from, to, departureTime);
    }

    @Override
    public double getTransportCost(Location from, Location to, double departureTime, Driver driver, Vehicle vehicle) {
        return callGoogleMapsDistanceApi(from, to, departureTime);
    }

    private double callGoogleMapsDistanceApi(Location from, Location to, double departureTime) {
        // implement a call to google maps
    }
}

Then vrpBuilder.setRoutingCost(new GoogleMapsVehicleRoutingTransportCosts());

NOTE: This will be very expensive in both time and API calls so you may want to consider a cache.

yasha-spare commented 3 years ago

Re: "This will be very expensive in both time and API calls so you may want to consider a cache.", regardless of what system you're using for routing costs (Google Maps, GraphHopper, OSRM, etc.), a common approach is to make a "routing costs matrix" type call to get all possible costs before you even start to solve the problem.

For example, say you have 100 locations in your problem, at the start of the problem you make a single call to the your routing costs system to get a matrix of all times and distances between all those locations, i.e. a 100x100 matrix. You then use that matrix to build jsprit routing costs, that you simply pass in to your problem. So you aren't making individual API calls for each location, you just make one big "cost matrix" call at the start of your problem, which tends to be way faster and cheaper.

For the Google Maps API specifically, you can use the Distance Matrix API to get this sort of cost matrix: https://developers.google.com/maps/documentation/distance-matrix/overview

It's still extremely expensive, though. A lot of people will run their own open source solution for cost matrixes, i.e. something like GraphHopper or OSRM.