【问题标题】:Zooming in/out some tiles not rendering - Osmdroid offline maps放大/缩小一些不渲染的图块 - Osmdroid 离线地图
【发布时间】:2016-02-14 15:10:37
【问题描述】:

我正在从资产加载图块,这是我的代码,用于初始化地图:

    mapView = (MapView)findViewById(R.id.offline_map_view); 
    mapView.setClickable(true);
    mapView.setBuiltInZoomControls(false);
    mapView.setMaxZoomLevel(macroZoomLevel);
    mapView.setMinZoomLevel(macroZoomLevel);
    mapView.getController().setZoom(macroZoomLevel); //set initial zoom-level, depends on your need
    mapView.setTileSource(new XYTileSource("MapQuest", 0, 18, 256, ".png",new String[] {"file:///android_asset/try/"} ));
    mapView.setUseDataConnection(false); //keeps the mapView from loading online tiles usi1ng network connection.
    mapView.getController().setCenter(new GeoPoint(54.370958, 18.589210));
    giveMarkersForActualLevel();

在我尝试放大之前一切正常,有些地图无法正确渲染。然后我缩小,然后开始正确渲染的区域现在有一些灰色瓷砖。

首先我用的是osmdroid 4.3,这样添加的:

 compile 'org.osmdroid:osmdroid-android:4.3'

然后我尝试使用最新版本的osmdroid,通过websitecompile 'org.osmdroid:osmdroid-android:5.1@aar'中描述的方法导入它

然后我从源代码中阅读了here tu build,因此我下载了最新的源代码,通过 gradle 构建它并添加了aar 文件osmdroid-android-release.aar。 这也不能解决我的问题。

放大和缩小后,我正在删除标记并添加另一个标记,因此我尝试以这种方式刷新地图。

((View)mapView.getParent()).invalidate();
mapView.invalidate();
mapView.postInvalidate();

Marker startMarker = new Marker(mapView);
startMarker.setPosition(new GeoPoint(54.337385, 18.662132));
setPropertiesForTopMarker(startMarker);
mapView.getOverlays().add(startMarker);

Marker startMarker1 = new Marker(mapView);
startMarker1.setPosition(new GeoPoint(54.332781, 18.587932));
setPropertiesForTopMarker(startMarker1);
mapView.getOverlays().add(startMarker1);

mapView.invalidate();
((View)mapView.getParent()).invalidate();
mapView.invalidate();
mapView.postInvalidate();

但它也不起作用。

您有什么想法,如何解决这个问题?

已编辑:

我尝试从源代码构建 osmdroid 以更改 @spy 提到的这个值。我的 logcat 的调试看起来不错。 Here 是日志。此处无法粘贴,因为行数太多。

我尝试以这种方式添加磁贴提供程序:

 final IRegisterReceiver registerReceiver = new SimpleRegisterReceiver(getApplicationContext());

        final ITileSource tileSource = new XYTileSource("MapQuest", 12, 14, 256, ".png",new String[] {"file:///android_asset/MapQuest/"} );

        final MapTileFilesystemProvider fileSystemProvider = new MapTileFilesystemProvider(
                registerReceiver, tileSource);

        final MapTileProviderArray tileProviderArray = new MapTileProviderArray(
                tileSource, registerReceiver, new MapTileModuleProviderBase[] {
                fileSystemProvider});

        mapView = new MapView(this, new DefaultResourceProxyImpl(this), tileProviderArray); 

或者这样

 final IRegisterReceiver registerReceiver = new SimpleRegisterReceiver(getApplicationContext());

            final ITileSource tileSource = new XYTileSource("MapQuest", 12, 14, 256, ".png",new String[] {"file:///android_asset/MapQuest/"} );

            final MapTileFilesystemProvider fileSystemProvider = new MapTileFilesystemProvider(
                    registerReceiver, tileSource);

            final MapTileProviderArray tileProviderArray = new MapTileProviderArray(
                    tileSource, registerReceiver, new MapTileModuleProviderBase[] {
                    fileSystemProvider});

 TilesOverlay tilesOverlay =
                new TilesOverlay(tileProviderArray, getApplicationContext());

        mapView.getOverlays().add(tilesOverlay);

但是这两种方法都没有显示任何地图。 Source 此代码。

【问题讨论】:

  • 你确定你有那个缩放级别的图块吗?
  • 如果我没有那个级别的图块,放大后我看不到任何图块。更重要的是,如果我回到初始缩放级别,我可以看到一些灰色图块,以前以正确的方式呈现。当我回到家时,我会尝试用更多细节更新问题。
  • 我有同样的问题,我还不知道原因,但是在放大和缩小时,我多次出现以下消息:“在正在使用的位图上调用了重新配置!这可能导致图形损坏!”我正在使用 OSMDroid 5.1 并针对 Android M

标签: android osmdroid android-assets


【解决方案1】:

值得一试...

如果您只想加载资源,请使用仅包含断言加载器的自定义 tile 提供程序数组。在上面的配置中,它仍然是在线机制(okhttp 或设备上的任何东西)尝试从 file:/// 下载文件,这可能与文件 url 有奇怪的行为。

还可以尝试通过 OpenStreetMapTileProviderConstants.DEBUGMODE 和 DEBUG_TILE_PROVIDERS 开启 tile 调试。它可能会揭示根本原因

【讨论】:

  • 感谢这个提示,我将尝试以这种方式调查这个问题;)
  • 您还有其他想法吗?您是否一直在使用离线地图,也许您知道更好的解决方案或其他库?
【解决方案2】:

好的,最后我使用Providers 解决了我的问题。

我对取自this 答案的代码做了一些修改,所以现在看起来像这样。

        mapView.setClickable(true);
        mapView.setBuiltInZoomControls(false);

        mapView.setMaxZoomLevel(macroZoomLevel);
        mapView.setMinZoomLevel(macroZoomLevel);
        mapView.getController().setZoom(macroZoomLevel); //set initial zoom-level, depends on your need

        mapView.setUseDataConnection(false); //keeps the mapView from loading online tiles usi1ng network connection.
        mapView.getController().setCenter(new GeoPoint(54.370958, 18.589210));

        // save zip to sd
        AssetManager assetManager = this.getAssets();
        InputStream is;
        String fileName = "map.zip";    // the zip file lies in assets root
        String path = this.getExternalFilesDir(null) + File.separator + fileName; // the path I save SD to

        File tileFile = new File(path);
        if(!tileFile.exists()) {
            try {
                is = assetManager.open(fileName);

                FileOutputStream fo = new FileOutputStream(path);

                byte[] b = new byte[1024];
                int length;
                while((length = is.read(b)) != -1) {
                    fo.write(b, 0, length);
                }

                fo.flush();
                fo.close();
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        IArchiveFile[] archives = new IArchiveFile[1];
        archives[0] = ArchiveFileFactory.getArchiveFile(tileFile);

        // Simple implementation that extends BitmapTileSourceBase and nothing else
        CustomTileSource customTiles = new CustomTileSource("MapQuest", null, 10, 14, 256, ".png");  // Maverik is the name of the folder inside the zip (so zip is map.zip and inside it is a folder called Maverik)

        MapTileModuleProviderBase[] providers = new MapTileModuleProviderBase[1];
        providers[0] = new MapTileFileArchiveProvider(new SimpleRegisterReceiver(this.getApplicationContext()), customTiles, archives);    // this one is for local tiles (zip etc.)



        MapTileProviderArray tileProvider = new MapTileProviderArray(customTiles,
                new SimpleRegisterReceiver(this.getApplicationContext()), providers);
        tilesOverlay = new TilesOverlay(tileProvider, this.getApplicationContext());
        tilesOverlay.setLoadingBackgroundColor(Color.TRANSPARENT);  // this makes sure that the invisble tiles of local tiles are transparent so we can see tiles from web, transparent have a minor performance decline.

        mapView.getOverlays().add(tilesOverlay);

CustomTileSource 看起来像这样:

public class CustomTileSource extends BitmapTileSourceBase {

    public CustomTileSource(String aName, ResourceProxy.string aResourceId, int aZoomMinLevel, int aZoomMaxLevel, int aTileSizePixels, String aImageFilenameEnding) {
        super(aName, aResourceId, aZoomMinLevel, aZoomMaxLevel, aTileSizePixels, aImageFilenameEnding);
    }
}

所以这只是BitmapTileSourceBase 的子类,没有任何额外的方法。

我有一个assets zip类型的文件,名字是map.zip,这个目录的结构是这样的:

map.zip/MapQuest/[lvlOfZoom]/[x]/[y.png]

现在它可以正常工作了,我只在单击我的标记时进行缩放,用户通过手势无法做到这一点。

如果您在实施我描述的方法时遇到一些问题,或者您不清楚,我会尝试在 cmets 中为您提供帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-30
    • 2014-04-12
    • 2012-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-07
    • 2022-08-23
    相关资源
    最近更新 更多