Search in sources :

Example 11 with ResourceManager

use of net.osmand.plus.resources.ResourceManager in project Osmand by osmandapp.

the class MapTileLayer method drawTileMap.

public void drawTileMap(Canvas canvas, RotatedTileBox tileBox) {
    ITileSource map = this.map;
    if (map == null) {
        return;
    }
    ResourceManager mgr = resourceManager;
    int nzoom = tileBox.getZoom();
    final QuadRect tilesRect = tileBox.getTileBounds();
    // recalculate for ellipsoid coordinates
    float ellipticTileCorrection = 0;
    if (map.isEllipticYTile()) {
        ellipticTileCorrection = (float) (MapUtils.getTileEllipsoidNumberY(nzoom, tileBox.getLatitude()) - tileBox.getCenterTileY());
    }
    int left = (int) Math.floor(tilesRect.left);
    int top = (int) Math.floor(tilesRect.top + ellipticTileCorrection);
    int width = (int) Math.ceil(tilesRect.right - left);
    int height = (int) Math.ceil(tilesRect.bottom + ellipticTileCorrection - top);
    boolean useInternet = (OsmandPlugin.getEnabledPlugin(OsmandRasterMapsPlugin.class) != null || OsmandPlugin.getEnabledPlugin(MapillaryPlugin.class) != null) && settings.USE_INTERNET_TO_DOWNLOAD_TILES.get() && settings.isInternetConnectionAvailable() && map.couldBeDownloadedFromInternet();
    int maxLevel = map.getMaximumZoomSupported();
    int tileSize = map.getTileSize();
    boolean oneTileShown = false;
    for (int i = 0; i < width; i++) {
        for (int j = 0; j < height; j++) {
            int leftPlusI = left + i;
            int topPlusJ = top + j;
            int x1 = tileBox.getPixXFromTileXNoRot(leftPlusI);
            int x2 = tileBox.getPixXFromTileXNoRot(leftPlusI + 1);
            int y1 = tileBox.getPixYFromTileYNoRot(topPlusJ - ellipticTileCorrection);
            int y2 = tileBox.getPixYFromTileYNoRot(topPlusJ + 1 - ellipticTileCorrection);
            bitmapToDraw.set(x1, y1, x2, y2);
            final int tileX = leftPlusI;
            final int tileY = topPlusJ;
            Bitmap bmp = null;
            String ordImgTile = mgr.calculateTileId(map, tileX, tileY, nzoom);
            // asking tile image async
            boolean imgExist = mgr.tileExistOnFileSystem(ordImgTile, map, tileX, tileY, nzoom);
            boolean originalWillBeLoaded = useInternet && nzoom <= maxLevel;
            if (imgExist || originalWillBeLoaded) {
                bmp = mgr.getBitmapTilesCache().getTileForMapAsync(ordImgTile, map, tileX, tileY, nzoom, useInternet);
            }
            if (bmp == null) {
                int div = 1;
                boolean readFromCache = originalWillBeLoaded || imgExist;
                boolean loadIfExists = !readFromCache;
                // asking if there is small version of the map (in cache)
                int allowedScale = Math.min(OVERZOOM_IN + Math.max(0, nzoom - map.getMaximumZoomSupported()), 8);
                int kzoom = 1;
                for (; kzoom <= allowedScale; kzoom++) {
                    div *= 2;
                    String imgTileId = mgr.calculateTileId(map, tileX / div, tileY / div, nzoom - kzoom);
                    if (readFromCache) {
                        bmp = mgr.getBitmapTilesCache().get(imgTileId);
                        if (bmp != null) {
                            break;
                        }
                    } else if (loadIfExists) {
                        if (mgr.tileExistOnFileSystem(imgTileId, map, tileX / div, tileY / div, nzoom - kzoom) || (useInternet && nzoom - kzoom <= maxLevel)) {
                            bmp = mgr.getBitmapTilesCache().getTileForMapAsync(imgTileId, map, tileX / div, tileY / div, nzoom - kzoom, useInternet);
                            break;
                        }
                    }
                }
                if (bmp != null) {
                    int xZoom = (tileX % div) * tileSize / div;
                    int yZoom = (tileY % div) * tileSize / div;
                    // nice scale
                    boolean useSampling = kzoom > 3;
                    bitmapToZoom.set(Math.max(xZoom, 0), Math.max(yZoom, 0), Math.min(xZoom + tileSize / div, tileSize), Math.min(yZoom + tileSize / div, tileSize));
                    if (!useSampling) {
                        canvas.drawBitmap(bmp, bitmapToZoom, bitmapToDraw, paintBitmap);
                    } else {
                        int margin = 1;
                        int scaledSize = tileSize / div;
                        float innerMargin = 0.5f;
                        RectF src = new RectF(0, 0, scaledSize, scaledSize);
                        if (bitmapToZoom.left >= margin) {
                            bitmapToZoom.left -= margin;
                            src.left = innerMargin;
                            src.right += margin;
                        }
                        if (bitmapToZoom.top >= margin) {
                            bitmapToZoom.top -= margin;
                            src.top = innerMargin;
                            src.bottom += margin;
                        }
                        if (bitmapToZoom.right + margin <= tileSize) {
                            bitmapToZoom.right += margin;
                            src.right += margin - innerMargin;
                        }
                        if (bitmapToZoom.bottom + margin <= tileSize) {
                            bitmapToZoom.bottom += margin;
                            src.bottom += margin - innerMargin;
                        }
                        Matrix m = new Matrix();
                        RectF dest = new RectF(0, 0, tileSize, tileSize);
                        m.setRectToRect(src, dest, Matrix.ScaleToFit.FILL);
                        Bitmap sampled = Bitmap.createBitmap(bmp, bitmapToZoom.left, bitmapToZoom.top, bitmapToZoom.width(), bitmapToZoom.height(), m, true);
                        bitmapToZoom.set(0, 0, tileSize, tileSize);
                        // very expensive that's why put in the cache
                        mgr.getBitmapTilesCache().put(ordImgTile, sampled);
                        canvas.drawBitmap(sampled, bitmapToZoom, bitmapToDraw, paintBitmap);
                    }
                }
            } else {
                bitmapToZoom.set(0, 0, tileSize, tileSize);
                canvas.drawBitmap(bmp, bitmapToZoom, bitmapToDraw, paintBitmap);
            }
            if (bmp != null) {
                oneTileShown = true;
            }
        }
    }
    if (mainMap && !oneTileShown && !useInternet && warningToSwitchMapShown < 3) {
        if (resourceManager.getRenderer().containsLatLonMapData(view.getLatitude(), view.getLongitude(), nzoom)) {
            Toast.makeText(view.getContext(), R.string.switch_to_vector_map_to_see, Toast.LENGTH_LONG).show();
            warningToSwitchMapShown++;
        }
    }
}
Also used : RectF(android.graphics.RectF) Bitmap(android.graphics.Bitmap) Matrix(android.graphics.Matrix) ITileSource(net.osmand.map.ITileSource) ResourceManager(net.osmand.plus.resources.ResourceManager) QuadRect(net.osmand.data.QuadRect) SuppressLint(android.annotation.SuppressLint) Paint(android.graphics.Paint)

Aggregations

ResourceManager (net.osmand.plus.resources.ResourceManager)11 Paint (android.graphics.Paint)3 IOException (java.io.IOException)3 ArrayList (java.util.ArrayList)3 QuadRect (net.osmand.data.QuadRect)3 ITileSource (net.osmand.map.ITileSource)3 SuppressLint (android.annotation.SuppressLint)2 DisplayMetrics (android.util.DisplayMetrics)2 View (android.view.View)2 AdapterView (android.widget.AdapterView)2 CompoundButton (android.widget.CompoundButton)2 ImageView (android.widget.ImageView)2 TextView (android.widget.TextView)2 Point (com.vividsolutions.jts.geom.Point)2 HashMap (java.util.HashMap)2 LinkedList (java.util.LinkedList)2 List (java.util.List)2 BinaryMapDataObject (net.osmand.binary.BinaryMapDataObject)2 GeometryTile (net.osmand.data.GeometryTile)2 QuadPointDouble (net.osmand.data.QuadPointDouble)2