Conversation
| If your input can contain the same coordinate many times, share a single `Location` instance | ||
| per coordinate — `LocationDeduplicator` and `UniqueLocationAccumulator` in | ||
| `ai.timefold.solver.service.maps.api` are there for exactly that — so the matrix stays as small | ||
| as the set of distinct sites. Building a matrix is roughly quadratic in the number of locations, |
There was a problem hiding this comment.
Well, it is a memory optimization, but for datasets with repeated visits on the same locations it's a crucial one. Since Location has no ID, it's always deserialized as a new instance from the JSON payload.
| } | ||
|
|
||
| @Override | ||
| public Optional<String> getLocationSetName() { // <2> |
There was a problem hiding this comment.
The LocationSet is better to describe among advanced topics; it's handful to optimize subsequent requests to roughly the same dataset, but not needed for most models in the beginning.
The LocationsAwareSolverModel could perhaps make the method return Optional.empty() by default.
| `getLocations()` is called on a model that may not be fully initialized yet. | ||
| Guard against null collections so that the enricher sees an empty list rather than a | ||
| `NullPointerException`. |
There was a problem hiding this comment.
If this is a real problem, the enricher should fail fast with a well-described NPE and this entire note would not be needed.
| [#mapServiceLocationAware] | ||
| == Using driving times in the domain | ||
|
|
||
| Because the matrix lives inside the `Location` objects, the rest of the domain model reads |
There was a problem hiding this comment.
Do you have any example of when you would treat all the objects with a Location interchangeably? None of our models actually does that, so I wonder if there is a example of how it could be useful.
| <<mapServiceCustomProvider>>. | ||
| ==== | ||
|
|
||
| [#mapServiceCustomProvider] |
There was a problem hiding this comment.
I suggest we take this out of scope for now.
It requires running an endpoint and registering its URL in the platform so that the map service can talk to it and download the map data.
I would recommend documenting this only once we have such a customer request.
|
|
||
| Creating and populating a named location set is a management operation on the map service, not | ||
| something your solver model does. Consult the Timefold Platform documentation for how to create | ||
| one. TODO: REF TO THOSE DOCS |
There was a problem hiding this comment.
I think this is as much as we have: https://docs.timefold.ai/timefold-platform/latest/how-tos/maps-service#location_sets
| Build the matrix yourself in the test fixture, using the same Haversine provider the platform uses | ||
| for its local computation: | ||
|
|
||
| [source,java] | ||
| ---- | ||
| import ai.timefold.solver.service.maps.haversine.impl.HaversineTravelTimeAndDistanceMatrixProvider; | ||
| import ai.timefold.solver.service.maps.service.test.api.TestDistanceCalculator; | ||
|
|
||
| private static final HaversineTravelTimeAndDistanceMatrixProvider PROVIDER = | ||
| new HaversineTravelTimeAndDistanceMatrixProvider(new ObjectMapper()); | ||
|
|
||
| public static VehicleRoutePlan initDistanceMap(VehicleRoutePlan plan) { | ||
| TestDistanceCalculator.initDistanceMaps(plan.getLocations(), // <1> | ||
| PROVIDER::calculateDistance, | ||
| PROVIDER::calculateTravelTime); | ||
| return plan; | ||
| } |
There was a problem hiding this comment.
This creates the impression that you need both the Haversine and the TestDistanceCalculator together.
You don't and specifically for tests, I would advise against that: in tests, pretty, easily verifiable numbers are preferred. The TestDistanceCalculator is a stub that returns what you want:
@rsynek, need your help pulling this over the finish line.