private void generateDistanceMatrix(final SimpleProgressDialog dialog, final ExecutorService executor) {
        loadCachedDistances();
        final AtomicInteger progress = new AtomicInteger(0);
        final List<Future<Object>> taskList = new ArrayList<>();
        try {
            for (int i = 0; i < routeSize; i++) {
                final int col = i;
                taskList.add(executor.submit(() -> {
                    for (int j = 0; j < routeSize; j++) {
                        if (col != j) {
                            final Integer temp = cachedDistances.distances.get(getCacheKey(initialRoute.get(col).getPoint(), initialRoute.get(j).getPoint()));
                            if (temp != null && temp != Integer.MAX_VALUE) {
                                distanceMatrix[col][j] = temp;
                            } else {
                                final Geopoint[] track = Routing.getTrackNoCaching(
                                        new Geopoint(initialRoute.get(col).getPoint().getLatitude(), initialRoute.get(col).getPoint().getLongitude()),
                                        new Geopoint(initialRoute.get(j).getPoint().getLatitude(), initialRoute.get(j).getPoint().getLongitude()),
                                        null);
                                float distance = 0.0f;
                                if (track.length > 0) {
                                    Geopoint last = track[0];
                                    for (Geopoint point : track) {
                                        distance += last.distanceTo(point);
                                        last = point;
                                    }
                                }
                                distanceMatrix[col][j] = (int) (1000.0f * distance);
                            }
                            progress.set(progress.get() + 1);
                            dialog.postProgress(progress.get() + 1);
                            if (Thread.currentThread().isInterrupted()) {
                                return 1;
                            }
                        }
                    }
                    return 1;
                }));
            }
            for (Future<Object> future : taskList) {
                future.get();
            }
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }
generate matrix of all distances between pairs
main/src/main/java/cgeo/geocaching/maps/routing/RouteOptimizationHelper.java