OSMdroid如何在运行时更改TileSource

3
我正在使用osmdroid,并希望能够在运行时(通过菜单项)更改TileSource。例如,我可以在OSM TileSource和GoogleTileSource之间进行切换。
问题是:一切都很好,但当我在地图视图正在后台加载瓦片时更改 TileSource 时,它会更改 TileSource,但仍会有一个或两个瓦片来自之前的 TileSource。因此,我会看到一个混合的 MapView,其中包含 OSMTiles 和一个或两个 GoogleTiles。
每次更改 TileSource 后都会清除 tileCache。但是,此时后台的加载瓦片不在缓存中,所以它在清除后将此瓦片放入缓存中。
有任何解决此问题的想法吗?这全部基于 osmdroid,我只使用 setTileSource(ITileSource)。
谢谢。

你从哪里获取Google瓦片?我在TileSourceFactory的常量选项中没有看到这个选项。 - NickT
我在教程中读到过这样的内容,离线使用谷歌地图是不允许的。但他告诉我可以缓存,所以他缓存了一些年份的瓦片 :) http://datamoil.blogspot.com/2011/05/offline-google-maps-on-osmdroid.html - Informatic0re
@Mirko:如果你打算发布一个使用Google瓦片的应用程序,我建议你先咨询一些好的法律意见。我不希望你被Google起诉。个人认为,如果这些瓦片是使用Mobac 1.8创建的,那么这就是违反许可协议,但是我并不是律师。 - NickT
@NickT 不用担心,我知道这个问题,我只是把谷歌地图瓦片放到这个应用程序中来测试是否可行。如果我需要谷歌地图,我会使用谷歌的MapView!但还是谢谢你的建议。 - Informatic0re
我曾经遇到过类似的问题,但是原因是我犯了一个愚蠢的错误,即将我的OnlineTileSourceBase / ITileSource子类的构造函数传递了相同(非唯一)的“名称”。 - Dwight Gunning
显示剩余3条评论
3个回答

1

看起来这是一个真正的bug。我认为你应该将其报告为bug。在问题列表中,我没有看到任何类似的情况。看起来坏的瓷砖甚至进入了SD卡上错误的缓存,这很糟糕,因为它会在那里停留一段时间。


1

如果您正在使用osmdroid3.0.6.jar(我认为您是,因为如果我使用3.0.6构建,我可以重现此错误),我认为这是我提出的问题osmdroid-android-3.0.6.jar,瓦片加载缓慢或失败的另一种表现。该错误已被作者接受。

我建议您回到使用3.0.5 jar。我没有任何问题。(我仍然困惑于您如何使用Osmdroid与Google瓦片)


谢谢,我也认为这是一个 bug。(对于 Google 地图瓦片,您只需要访问此页面 http://mt3.google.com/vt/v=w2.97&x=74327&y=50500&z=17 并为 osmdroid 创建自己的 TileSource 即可) - Informatic0re
我认为这是一个不同的问题,我刚刚在我的应用程序中回到了3.0.5版本,并看到了相同的效果。 - Ifor
在我的情况下,它也不慢。我查看了osmdroid的源代码。在setTileSource()方法中,它清除了缓存,但没有停止当前的下载或其他操作。因此,缓存是干净的,但下载正在进行,当下载完成后,它将瓦片放入缓存中。因此,可能会将1或2个旧的TileSource瓦片放入缓存中,然后是新的瓦片。我找到了一个解决方法,但并不是很好,我会将其作为答案提供。 - Informatic0re

0

我认为我们都认为这是一个错误(或者可能不希望在运行时切换TileSource)。

我创建了一个小的解决方法。它可以工作,但并不是真正好的或推荐的。

我创建了一个新的mapView并扩展了osm MapView。然后创建了一个RequestCompleteHandler,这样我就可以看到何时完成加载瓷砖并保存到缓存中。然后我计算每个缓存的瓷砖,并只允许在加载15个瓷砖后切换tileSource。(在应用程序启动时,osmdroid将加载15个瓷砖,并在移动地图后仅加载一些更多的瓷砖)

class RequestCompleteHandler extends SimpleInvalidationHandler{
    private LbsMapView mMapView;

    public RequestCompleteHandler(LbsMapView pView) {
        super(pView);
        mMapView = pView;
    }

    @Override
    public void dispatchMessage(Message msg) {
        super.dispatchMessage(msg);
        Log.d("DEBUG", "HANDLER HAT GERUFEN! BACKE BACKE KUCHEN!! " + tileCount);
        tileCount++;
    }

}

然后覆盖setTileSource方法:

@Override
public void setTileSource(ITileSource aTileSource) {
    if(tileCount <= 15){
        Toast.makeText(mContext, "Jetz eher nich", Toast.LENGTH_SHORT).show();
    } else {
        tileCount = 0;
        super.setTileSource(aTileSource);
    }

}

你需要在构造函数中设置和初始化处理程序:

mHandler = new RequestCompleteHandler(this);
    getTileProvider().setTileRequestCompleteHandler(mHandler);

完成。现在只有在加载了15个瓷砖后才能切换tileSource。 有一个小问题:如果源不起作用并且没有加载任何瓷砖,您就会遇到问题:D

但是重要的是:不建议这样做,这是非常丑陋的代码。


你确定它总是会有15个瓷砖吗?我记得缓存开始时只有9个,然后增长到16个,至少在我的情况下是这样的,这是我在logcat中看到的。 - Ifor
我不是100%确定,我只在启动应用程序时计算了15个。但是如果您移动地图并切换TileSource,瓷砖也会混合。但用户需要快速操作。 - Informatic0re
我将其作为osmdroid的问题发布...在使用setTileSource后,他们需要清除下载队列,所以我认为我们需要等待一个新版本 :) - Informatic0re
我也遇到了完全相同的问题。是否已经记录了这个问题?如果是,能否给我一个链接? - Dwight Gunning

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接