geopackage-sdk/src/main/java/mil/nga/geopackage/tiles/retriever/TileCreator.java
private List<TileMatrix> getTileMatrices(BoundingBox projectedRequestBoundingBox) {

        List<TileMatrix> tileMatrices = new ArrayList<>();

        // Check if the request overlaps the tile matrix set
        if (!tileDao.getTileMatrices().isEmpty()
                && projectedRequestBoundingBox.intersects(
                tileSetBoundingBox)) {

            // Get the tile distance
            double distanceWidth = projectedRequestBoundingBox
                    .getMaxLongitude()
                    - projectedRequestBoundingBox.getMinLongitude();
            double distanceHeight = projectedRequestBoundingBox
                    .getMaxLatitude()
                    - projectedRequestBoundingBox.getMinLatitude();

            // Get the zoom level to request based upon the tile size
            Long requestZoomLevel = null;
            if (scaling != null) {
                // When options are provided, get the approximate zoom level regardless of whether a tile level exists
                requestZoomLevel = tileDao.getApproximateZoomLevel(distanceWidth, distanceHeight);
            } else {
                // Get the closest existing zoom level
                requestZoomLevel = tileDao.getZoomLevel(distanceWidth, distanceHeight);
            }

            // If there is a matching zoom level
            if (requestZoomLevel != null) {

                List<Long> zoomLevels = null;

                // If options are configured, build the possible zoom levels in order to request
                if (scaling != null && scaling.getScalingType() != null) {

                    // Find zoom in levels
                    List<Long> zoomInLevels = new ArrayList<>();
                    if (scaling.isZoomIn()) {
                        long zoomIn = scaling.getZoomIn() != null ? requestZoomLevel + scaling.getZoomIn() : tileDao.getMaxZoom();
                        for (long zoomLevel = requestZoomLevel + 1; zoomLevel <= zoomIn; zoomLevel++) {
                            zoomInLevels.add(zoomLevel);
                        }
                    }

                    // Find zoom out levels
                    List<Long> zoomOutLevels = new ArrayList<>();
                    if (scaling.isZoomOut()) {
                        long zoomOut = scaling.getZoomOut() != null ? requestZoomLevel - scaling.getZoomOut() : tileDao.getMinZoom();
                        for (long zoomLevel = requestZoomLevel - 1; zoomLevel >= zoomOut; zoomLevel--) {
                            zoomOutLevels.add(zoomLevel);
                        }
                    }

                    if (zoomInLevels.isEmpty()) {
                        // Only zooming out
                        zoomLevels = zoomOutLevels;
                    } else if (zoomOutLevels.isEmpty()) {
                        // Only zooming in
                        zoomLevels = zoomInLevels;
                    } else {
                        // Determine how to order the zoom in and zoom out levels
                        TileScalingType type = scaling.getScalingType();
                        switch (type) {
                            case IN:
                            case IN_OUT:
                                // Order zoom in levels before zoom out levels
                                zoomLevels = zoomInLevels;
                                zoomLevels.addAll(zoomOutLevels);
                                break;
                            case OUT:
                            case OUT_IN:
                                // Order zoom out levels before zoom in levels
                                zoomLevels = zoomOutLevels;
                                zoomLevels.addAll(zoomInLevels);
                                break;
                            case CLOSEST_IN_OUT:
                            case CLOSEST_OUT_IN:
                                // Alternate the zoom in and out levels

                                List<Long> firstLevels;
                                List<Long> secondLevels;
                                if (type == TileScalingType.CLOSEST_IN_OUT) {
                                    // Alternate starting with zoom in
                                    firstLevels = zoomInLevels;
                                    secondLevels = zoomOutLevels;
                                } else {
                                    // Alternate starting with zoom out
                                    firstLevels = zoomOutLevels;
                                    secondLevels = zoomInLevels;
                                }

                                zoomLevels = new ArrayList<>();
                                int maxLevels = Math.max(firstLevels.size(), secondLevels.size());
                                for (int i = 0; i < maxLevels; i++) {
                                    if (i < firstLevels.size()) {
                                        zoomLevels.add(firstLevels.get(i));
                                    }
                                    if (i < secondLevels.size()) {
                                        zoomLevels.add(secondLevels.get(i));
                                    }
                                }

                                break;
                            default:
                                throw new GeoPackageException("Unsupported " + TileScalingType.class.getSimpleName()
                                        + ": " + type);
                        }
                    }
                } else {
                    zoomLevels = new ArrayList<>();
                }

                // Always check the request zoom level first
                zoomLevels.add(0, requestZoomLevel);

                // Build a list of tile matrices that exist for the zoom levels
                for (long zoomLevel : zoomLevels) {
                    TileMatrix tileMatrix = tileDao.getTileMatrix(zoomLevel);
                    if (tileMatrix != null) {
                        tileMatrices.add(tileMatrix);
                    }
                }

            }
        }

        return tileMatrices;
    }
private List<TileMatrix> getTileMatrices(BoundingBox projectedRequestBoundingBox) {

        List<TileMatrix> tileMatrices = new ArrayList<>();

        // Check if the request overlaps the tile matrix set
        if (!tileDao.getTileMatrices().isEmpty()
                && projectedRequestBoundingBox.intersects(
                tileSetBoundingBox)) {

            // Get the tile distance
            double distanceWidth = projectedRequestBoundingBox
                    .getMaxLongitude()
                    - projectedRequestBoundingBox.getMinLongitude();
            double distanceHeight = projectedRequestBoundingBox
                    .getMaxLatitude()
                    - projectedRequestBoundingBox.getMinLatitude();

            // Get the zoom level to request based upon the tile size
            Long requestZoomLevel = null;
            if (scaling != null) {
                // When options are provided, get the approximate zoom level regardless of whether a tile level exists
                requestZoomLevel = tileDao.getApproximateZoomLevel(distanceWidth, distanceHeight);
            } else {
                // Get the closest existing zoom level
                requestZoomLevel = tileDao.getZoomLevel(distanceWidth, distanceHeight);
            }

            // If there is a matching zoom level
            if (requestZoomLevel != null) {

                List<Long> zoomLevels = null;

                // If options are configured, build the possible zoom levels in order to request
                if (scaling != null && scaling.getScalingType() != null) {

                    // Find zoom in levels
                    List<Long> zoomInLevels = new ArrayList<>();
                    if (scaling.isZoomIn()) {
                        long zoomIn = scaling.getZoomIn() != null ? requestZoomLevel + scaling.getZoomIn() : tileDao.getMaxZoom();
                        for (long zoomLevel = requestZoomLevel + 1; zoomLevel <= zoomIn; zoomLevel++) {
                            zoomInLevels.add(zoomLevel);
                        }
                    }

                    // Find zoom out levels
                    List<Long> zoomOutLevels = new ArrayList<>();
                    if (scaling.isZoomOut()) {
                        long zoomOut = scaling.getZoomOut() != null ? requestZoomLevel - scaling.getZoomOut() : tileDao.getMinZoom();
                        for (long zoomLevel = requestZoomLevel - 1; zoomLevel >= zoomOut; zoomLevel--) {
                            zoomOutLevels.add(zoomLevel);
                        }
                    }

                    if (zoomInLevels.isEmpty()) {
                        // Only zooming out
                        zoomLevels = zoomOutLevels;
                    } else if (zoomOutLevels.isEmpty()) {
                        // Only zooming in
                        zoomLevels = zoomInLevels;
                    } else {
                        // Determine how to order the zoom in and zoom out levels
                        TileScalingType type = scaling.getScalingType();
                        switch (type) {
                            case IN:
                            case IN_OUT:
                                // Order zoom in levels before zoom out levels
                                zoomLevels = zoomInLevels;
                                zoomLevels.addAll(zoomOutLevels);
                                break;
                            case OUT:
                            case OUT_IN:
                                // Order zoom out levels before zoom in levels
                                zoomLevels = zoomOutLevels;
                                zoomLevels.addAll(zoomInLevels);
                                break;
                            case CLOSEST_IN_OUT:
                            case CLOSEST_OUT_IN:
                                // Alternate the zoom in and out levels

                                List<Long> firstLevels;
                                List<Long> secondLevels;
                                if (type == TileScalingType.CLOSEST_IN_OUT) {
                                    // Alternate starting with zoom in
                                    firstLevels = zoomInLevels;
                                    secondLevels = zoomOutLevels;
                                } else {
                                    // Alternate starting with zoom out
                                    firstLevels = zoomOutLevels;
                                    secondLevels = zoomInLevels;
                                }

                                zoomLevels = new ArrayList<>();
                                int maxLevels = Math.max(firstLevels.size(), secondLevels.size());
                                for (int i = 0; i < maxLevels; i++) {
                                    if (i < firstLevels.size()) {
                                        zoomLevels.add(firstLevels.get(i));
                                    }
                                    if (i < secondLevels.size()) {
                                        zoomLevels.add(secondLevels.get(i));
                                    }
                                }

                                break;
                            default:
                                throw new GeoPackageException("Unsupported " + TileScalingType.class.getSimpleName()
                                        + ": " + type);
                        }
                    }
                } else {
                    zoomLevels = new ArrayList<>();
                }

                // Always check the request zoom level first
                zoomLevels.add(0, requestZoomLevel);

                // Build a list of tile matrices that exist for the zoom levels
                for (long zoomLevel : zoomLevels) {
                    TileMatrix tileMatrix = tileDao.getTileMatrix(zoomLevel);
                    if (tileMatrix != null) {
                        tileMatrices.add(tileMatrix);
                    }
                }

            }
        }

        return tileMatrices;
    }
Get the tile matrices that may contain the tiles for the bounding box, matches against the bounding box and zoom level options

@param projectedRequestBoundingBox bounding box projected to the tiles
@return tile matrices