android - Android Maps V2 上的模糊自定义图 block

标签 android google-maps openstreetmap google-maps-api-2

我想在 Google Maps V2 上显示 CustomOverlay。瓷砖的加载按预期工作,唯一的问题是,显示的瓷砖根本不清晰,有点模糊。 Google 没有让我找到可用的答案。

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

我包含了渲染 map 的两个不同示例(屏幕截图),它们都具有相同的配置(OSM - 256x256 tiles)和提供的 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;
    }
 }

这是我将叠加层添加到 map 的方法:

 map.addTileOverlay(new TileOverlayOptions().tileProvider(new TileProviderOsm()));

以下是呈现的 Google map 的一些示例:

Google Maps V2 on a Nexus 5 - OSM Map tiles look blurry Google Maps V2 on a Galaxy Nexu - OSM Map tiles look blurry

最佳答案

我正在通过将四 block 瓷砖绘制成一 block 瓷砖来解决这个问题。

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

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;
    }
}

关于android - Android Maps V2 上的模糊自定义图 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23806348/

相关文章:

java - list.notify() 抛出异常

android - 使用 Anko 从 Activity 访问 View

android - 无法在 android studio 中创建新 Activity (NullPointerException)

ios - 为 iOS 模拟器构建,但链接到为 iOS 构建的目标文件,文件 '.../GoogleMaps' 为架构 arm64

linux - 为 OpenStreetMap 构建图 block 服务器时找不到包 apache2-dev-tile

java - 使用开放街道 map 规划路线

java - 如何在phonegap android中隐藏地址栏

Cordova ,内容安全策略 : within iframe getting error as deviceready has not fired after 5 seconds

android - Google Maps Android API v2,标记标题/fragment 错误显示

javascript - Google map 纹理 map