MatrixRequest & MatrixResult - accessing results

Kia ora!

I’ve finally figured out how to get a local install going (M1 Mac - 13.2.1, Java). I have this custom class, with which I intend to test the upper limits of running ORS locally (I’ve changed the maximum number of routes to 100,000,000):

private static APIEnums.Profile car;
private static MatrixRequest matrixLocationsRequest;
private static Double[][] bareCoordinates;

public static void main(String[] args) throws StatusCodeException {
	car = APIEnums.Profile.DRIVING_CAR;

	int n = 1000;
	float lon_min = 7.70847f; // I don't currently know how to change the default location ORS thinks we're handling.
	float lon_max = 9.10395f;
	float lat_min = 49.3326f;
	float lat_max = 49.5168f;

	bareCoordinates = new Double[n][];

	String st[] = new String[]{"all"};
	int i = 0;
	while (i < n){
		double lon = (float)Math.random() * (lon_max - lon_min) + lon_min;
		double lat = (float)Math.random() * (lat_max - lat_min) + lat_min;
		MatrixRequest tempReq = new MatrixRequest(new Double[][]{new Double[]{lon, lat}, new Double[]{lon, lat}});
		tempReq.setSources(st);
		tempReq.setDestinations(st);
		tempReq.setProfile(car);
		tempReq.setMetrics(new MatrixRequestEnums.Metrics[]{MatrixRequestEnums.Metrics.DURATION});
		tempReq.setResponseType(APIEnums.MatrixResponseType.JSON);

		MatrixResult res;
		try {
			res = tempReq.generateMatrixFromRequest();
			if(res != null && res.getTable(1)[0] == -1) // res.getTable(1)[x] should == 0, as from a valid node i to i == dist 0, but if == -1, we have failed to identify a valid points
				continue;
		} catch (Exception e){
			continue;
		}

		bareCoordinates[i] = new Double[] {lon, lat};
		i++;
	}

	System.out.println("fin random generation");
	long start = System.currentTimeMillis();

	matrixLocationsRequest = new MatrixRequest(bareCoordinates);
	matrixLocationsRequest.setResolveLocations(true);
	matrixLocationsRequest.setSources(st);
	matrixLocationsRequest.setDestinations(st);
	matrixLocationsRequest.setProfile(car);
	matrixLocationsRequest.setMetrics(new MatrixRequestEnums.Metrics[]{MatrixRequestEnums.Metrics.DURATION});
	matrixLocationsRequest.setResponseType(APIEnums.MatrixResponseType.JSON);
	MatrixResult res = matrixLocationsRequest.generateMatrixFromRequest();

	long end = System.currentTimeMillis();
	System.out.println("Comp time (s): " + ((end - start)/1000));

	float[] distances = res.getTable(1);
	System.out.println("distances len: " + distances.length);
	int count = 0;
	for (i = 0; i < distances.length; i++) {
		if (distances[i] != -1) {
			count++;
		}
	}
	System.out.println(count); // the number of feasible distance calculations
}

I have the following outstanding problems:

  1. I presume res.getTables()[1] (metric 1) refers to the requested DURATION metric?
  2. How do I parse the single-dimension values array (length 1,000,000)? Is the index of the cost (duration/distance) from node i to node j equal to index = j * n + i, where n is the number of destination nodes?
  3. Approximately 25% of the values in my res.getTables()[1] array equal -1. My only explanation for routes that can’t be found is if the graphs upon which point i and j occur are disconnected. Is someone able to confirm this? Note: these all occur when sptItem.getParent() == null in the calcValues method of the MultiTreeMetricsExtractor class. [linked question]
  4. I believe there are two cases for generating a value of 0: a) two randomly generated points are so (geographically) close that they snap to the same graph node (the rarest), and b) two geographic points are equal (the most common). Is this correct?
  5. I’ve tried changing the ors-config.json file in openrouteservice/target/classes to point to a custom .osm.pbf (osm.gz and .osm) file, but none have changed the bounding box that ORS defaults to using.

Appreciate your help.
Cheers

Hey,

it seems as if you’re trying to natively use the openrouteservice as a java package.

This is currently not intended. The way to go would be via the REST API.
Check the api docs for its usage.

Is there any particular reason as to why you’re doing this? Do you need access to the internal structures and classes openrouteservice is using?

For changing the .pbf-file used, it should suffice to change the value in the ors-config.json, not anywhere else. Note that you’ll have to rebuild the graphs, which won’t happen if there is a folder with the same name as the one configured configured in graphs_root_path

Best regards

Kia ora! Thank you for getting back to me on this.

I’m using the Java package not because I need access to all classes, but because I intend to make millions of requests per day for my PhD, and thus a local build is preferred. Calling a web-based API will be too slow and expensive for my requirements. I followed the install instructions from the OpenRouteService site to get it going in IntelliJ.

Thank you re: instructions for changing the map. Changing the name of the default graph directory has allowed ORS to generate a new one, thank you.

Hey,

as you’re using a local build, which I assume is running on your local machine, I think that the overhead of querying the openrouteservice via its http API as opposed to using it as a java package is negligible, especially given that this provides you the freedom of using any programming language of your choosing for post-processing the responses.

May I ask what kind of analysis you’re conducting to issue millions of requests per day?

Best regards

Hi jschnell,

Appreciate your following up.

Sorry, yes. I’m currently just running this on my local machine. However, I intend to run the Java package on a cluster for experimental testing in the coming weeks.

My research involves learning a machine learning model for a problem that has a considerable routing aspect. During training, I need to make approximately 100m path queries, and several hundred million distance queries at a city scale (for my small dataset…).

The limitation of using the API is primarily the limitation on the number of requests per minute. I expect to make approximately 1.5m requests per minute (x30 processes). If I can avoid this limitation, I might be able to scale efficiently - even if it requires I maintain a more complex codebase.

If you have any alternative suggestions, please shout.

Cheers,
Mak

Hey,

if you’re running your own openrouteservice instance locally, you don’t have any limitation on the number of requests per minute, but can query openrouteservice as fast as your machine will allow.

If you’re still worried about the http roundtrip overhead, I’d still suggest not trying to use any routing functionality directly, as if ors were a java package, but rather use the methods on the outermost layer, i.e. the ones that are being used in e.g. RoutingAPI

Best regards