Android Maps V2上的模糊自定义图块

Dev*_*oid 4 android google-maps openstreetmap google-maps-api-2

我想在Google Maps V2上显示CustomOverlay.瓷砖的装载按预期工作,唯一的是,所显示的瓷砖看起来并不尖锐,有点模糊.谷歌没有让我得到一个有用的答案.

我采用了为TileProvider添加经典256px x 256px磁贴的方法.我设法获得了一个图像为@ 2x(视网膜)的图像源,这使得整个视觉体验更加清晰,但我宁愿不使用此源,因为数据传输速率高四倍,因此无法在移动设备上使用设备和慢速的互联网速度.

我包含了渲染地图的两个不同示例(屏幕截图),两个都具有相同的配置(OSM - 256x256磁贴)和提供的TileProviderOsm.一个是Galaxy Nexus,另一个是Nexus 5手机.两者看起来都不正确.

知道我能做些什么来防止模糊或增加锐度?

我的TileProvider如下所示:

 public class TileProviderOsm extends UrlTileProvider {

    private static final String MAP_URL = "http://tile.openstreetmap.org/%d/%d/%d.png";

    private static int TILE_WIDTH  = 256;
    private static int TILE_HEIGHT = 256;

    public static int MIN_ZOOM = 7;
    public static int MAX_ZOOM = 15;

    public TileProviderOsm() {
        super(TILE_WIDTH, TILE_HEIGHT);
    }

    @Override
    public synchronized URL getTileUrl(int x, int y, int zoom) {

        String s = String.format(Locale.US, MAP_URL, zoom, x, y);
        URL url = null;
        try {
             url = new URL(s);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        return url;
    }
 }
Run Code Online (Sandbox Code Playgroud)

以下是我将叠加层添加到地图的方法:

 map.addTileOverlay(new TileOverlayOptions().tileProvider(new TileProviderOsm()));
Run Code Online (Sandbox Code Playgroud)

以下是渲染的Google地图的一些示例:

Nexus 5上的Google Maps V2  -  OSM地图图块看起来很模糊 Galaxy Nexu上的Google Maps V2  -  OSM地图图块看起来很模糊

Rad*_*ekJ 8

我通过在一个瓷砖上绘制四个瓷砖来解决这个问题.

我写了这个TileProvider,它使用另一个tile提供程序来创建更高分辨率的tile.

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;

import com.google.android.gms.maps.model.Tile;
import com.google.android.gms.maps.model.TileProvider;

import java.io.ByteArrayOutputStream;

public class CanvasTileProvider implements TileProvider {

    static final int TILE_SIZE = 512;
    private TileProvider mTileProvider;

    public CanvasTileProvider(TileProvider tileProvider) {
        mTileProvider = tileProvider;
    }

    @Override
    public Tile getTile(int x, int y, int zoom) {
        byte[] data;
        Bitmap image = getNewBitmap();
        Canvas canvas = new Canvas(image);
        boolean isOk = onDraw(canvas, zoom, x, y);
        data = bitmapToByteArray(image);
        image.recycle();

        if (isOk) {
            Tile tile = new Tile(TILE_SIZE, TILE_SIZE, data);
            return tile;
        } else {
            return mTileProvider.getTile(x, y, zoom);
        }
    }

    Paint paint = new Paint();

    private boolean onDraw(Canvas canvas, int zoom, int x, int y) {
        x = x * 2;
        y = y * 2;
        Tile leftTop = mTileProvider.getTile(x, y, zoom + 1);
        Tile leftBottom = mTileProvider.getTile(x, y + 1, zoom + 1);
        Tile rightTop = mTileProvider.getTile(x + 1, y, zoom + 1);
        Tile rightBottom = mTileProvider.getTile(x + 1, y + 1, zoom + 1);

        if (leftTop == NO_TILE && leftBottom == NO_TILE && rightTop == NO_TILE && rightBottom == NO_TILE) {
            return false;
        }


        Bitmap bitmap;

        if (leftTop != NO_TILE) {
            bitmap = BitmapFactory.decodeByteArray(leftTop.data, 0, leftTop.data.length);
            canvas.drawBitmap(bitmap, 0, 0, paint);
            bitmap.recycle();
        }

        if (leftBottom != NO_TILE) {
            bitmap = BitmapFactory.decodeByteArray(leftBottom.data, 0, leftBottom.data.length);
            canvas.drawBitmap(bitmap, 0, 256, paint);
            bitmap.recycle();
        }
        if (rightTop != NO_TILE) {
            bitmap = BitmapFactory.decodeByteArray(rightTop.data, 0, rightTop.data.length);
            canvas.drawBitmap(bitmap, 256, 0, paint);
            bitmap.recycle();
        }
        if (rightBottom != NO_TILE) {
            bitmap = BitmapFactory.decodeByteArray(rightBottom.data, 0, rightBottom.data.length);
            canvas.drawBitmap(bitmap, 256, 256, paint);
            bitmap.recycle();
        }
        return true;
    }

    private Bitmap getNewBitmap() {
        Bitmap image = Bitmap.createBitmap(TILE_SIZE, TILE_SIZE,
                Bitmap.Config.ARGB_8888);
        image.eraseColor(Color.TRANSPARENT);
        return image;
    }

    private static byte[] bitmapToByteArray(Bitmap bm) {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        bm.compress(Bitmap.CompressFormat.PNG, 100, bos);

        byte[] data = bos.toByteArray();
        try {
            bos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return data;
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 5

这是地图图块的缩放级别和缩放的问题.这似乎是Maps API V2 for Android的一个问题.据推测,这种行为的目的如下:gmaps-api-issues#4840

我通过从WMS请求更大的瓷砖来解决它 - 只需用512x512替换256x256.