public static void checkRoutingData(final Activity activity, final double minLatitude, final double minLongitude, final double maxLatitude, final double maxLongitude) {
        if (Settings.useInternalRouting()) {
            ActivityMixin.showToast(activity, R.string.downloadmap_checking);

            final HashMap<String, String> requiredTiles = new HashMap<>();
            final ArrayList<Download> missingDownloads = new ArrayList<>();
            final AtomicBoolean hasUnsupportedTiles = new AtomicBoolean(false);

            AndroidRxUtils.andThenOnUi(AndroidRxUtils.networkScheduler, () -> {
                // calculate affected routing tiles
                int curLat = (int) Math.floor(minLatitude / 5) * 5;
                final int maxLat = (int) Math.floor(maxLatitude / 5) * 5;
                final int maxLon = (int) Math.floor(maxLongitude / 5) * 5;
                while (curLat <= maxLat) {
                    int curLon = (int) Math.floor(minLongitude / 5) * 5;
                    while (curLon <= maxLon) {
                        final String filenameBase = (curLon < 0 ? "W" + (-curLon) : "E" + curLon) + "_" + (curLat < 0 ? "S" + (-curLat) : "N" + curLat) + BROUTER_TILE_FILEEXTENSION;
                        requiredTiles.put(filenameBase, filenameBase);
                        curLon += 5;
                    }
                    curLat += 5;
                }
                checkTiles(requiredTiles, missingDownloads, hasUnsupportedTiles);
            }, () -> {
                // give feedback to the user + offer to download missing tiles (if available)
                if (missingDownloads.isEmpty()) {
                    ActivityMixin.showShortToast(activity, hasUnsupportedTiles.get() ? R.string.check_tiles_unsupported : R.string.check_tiles_found);
                } else {
                    if (hasUnsupportedTiles.get()) {
                        ActivityMixin.showShortToast(activity, R.string.check_tiles_unsupported);
                    }
                    DownloaderUtils.triggerDownloads(activity, R.string.downloadtile_title, R.string.check_tiles_missing, missingDownloads, null);
                }
            });
        } else {
            // if external routing configured: try to open BRouter downloader
            try {
                final String bRouterPackage = activity.getString(R.string.package_brouter);
                final Intent intent = new Intent();
                intent.setComponent(new ComponentName(bRouterPackage, bRouterPackage + ".BInstallerActivity"));
                activity.startActivity(intent);
            } catch (ActivityNotFoundException ignore) {
                ActivityMixin.showShortToast(activity, R.string.cache_not_status_found);
            }
        }
    }
Applies given filter to cache list. Additionally, creates a second list additionally filtered by own/found/disabled caches if required
main/src/main/java/cgeo/geocaching/maps/MapUtils.java