自定义图块覆盖在最新的适用于 Android 的 Google Maps SDK 中不起作用

Posted

技术标签:

【中文标题】自定义图块覆盖在最新的适用于 Android 的 Google Maps SDK 中不起作用【英文标题】:Custom Tiles overlay not working in latest Google Maps SDK for Android 【发布时间】:2020-02-12 01:58:42 【问题描述】:

我正在尝试使用addTileOverlay 和自定义图块提供程序在 google maps sdk for android 中显示 OpenCycleMaps,但它在最新版本的 SDK 中不起作用。

这是我正在使用的 SDK 版本 -

com.google.android.gms:play-services-maps:17.0.0

这是我用来显示自定义图块的代码。在这里,我将地图设置为无,然后改为显示自定义图块 -

val SYDNEY = LatLng(-33.862, 151.21)
val ZOOM_LEVEL = 13f

override fun onMapReady(googleMap: GoogleMap?) 
        googleMap ?: return
        with(googleMap) 
            moveCamera(CameraUpdateFactory.newLatLngZoom(SYDNEY, ZOOM_LEVEL))
            addMarker(MarkerOptions().position(SYDNEY))
            mapType = GoogleMap.MAP_TYPE_NONE
            val mTileProvider = MyUrlTileProvider(256, 256, "http://a.tile.opencyclemap.org/cycle/z/x/y.png")
            addTileOverlay(TileOverlayOptions().tileProvider(mTileProvider))
        
    

这是自定义 tile 提供程序类 -

class MyUrlTileProvider(width: Int, height: Int, private val baseUrl: String) : UrlTileProvider(width, height) 

    override fun getTileUrl(x: Int, y: Int, zoom: Int): URL? 
        try 
            return URL(baseUrl.replace("z", "" + zoom).replace("x", "" + x).replace("y", "" + y))
         catch (e: MalformedURLException) 
            e.printStackTrace()
        

        return null
    

为了确保问题不在我的代码中,我在https://github.com/googlemaps/android-samples/tree/master/ApiDemos/kotlin 中尝试了同样的^ 代码,因为他们还没有升级到androidX 并且仍在使用play-services-maps:11.8.0,所以它在那里工作;正在显示自定义图块。在升级相同的代码以使用最新的地图 SDK 时,它停止工作。

【问题讨论】:

【参考方案1】:

问题根本不在于 TileProvider 或 Google 地图组件。问题在于磁贴网址。其中的第一个问题是 url 是 http,请求失败。第二个问题是 a.tile.opencyclemap.org 在 Android 上无法解决。所以我查找了 OSM wiki 并找到了 opencyclemaps 的这个 url - http://tile.thunderforest.com/cycle/$z/$x/$y.png 非常有效。

这是工作代码 -

mapType = GoogleMap.MAP_TYPE_NONE
val mTileProvider = MyUrlTileProvider(256, 256, "https://tile.thunderforest.com/cycle/z/x/y.png.png")
addTileOverlay(TileOverlayOptions().tileProvider(mTileProvider))

【讨论】:

认为一个人甚至不需要任何第三方提供者,但可以设计它;曾经回答过类似的传输层问题,但我现在正在打电话。我的意思是,当尝试将路线传递给导航时,差异应该会变得更加明显。 第三方提供商是什么意思? OpenCycleMap 由 Thunderforest Maps 正式拥有和开发。 第三方提供者是任何不是谷歌的实体......并且与“导航”应用程序的平滑集成可能只适用于谷歌地图传输层;否则,必须从两个路由提供商处查找相同的路由。它始终取决于应用程序;例如。 MapQuest 也适用于路由,因为它没有 Google 所具有的某些限制(或在使其成为付费 API 之前)。我曾经需要的 API 仅适用于企业客户,每月花费大约 7 美元;随着新的定价方案,这可能已经改变。 Thunderforest Maps 可能不提供任何 SLA。 抱歉,问题根本不在于路线,也不在于是否需要这些地图图块进行导航。我只想知道为什么自定义地图图块不适合我;这得到了解决。关于您的第一条评论,谷歌地图可以设置样式,但它不显示自行车路线等数据,这些数据只能通过外部地图图块提供商获得。因此这是必需的。不过还是谢谢。 我遇到了类似的问题。事实证明,有时 OSM 或 Mapbox 服务器可能会关闭,或者可能会阻止您一段时间,这大概就是当其他 tile 提供商没有时,雷霆森林工作的原因。如果发生这种情况(例如,它适用于 29 以下的 api 但不适用于 29,请耐心等待)。【参考方案2】:

对我来说没问题。

    尝试将.visible(true) 添加到.tileProvider(mTileProvider)).visible(true) 在 TileProvider 中制作更好的 URL:
class TileProvider(var time: Long) : UrlTileProvider(256, 256) 
   override fun getTileUrl(x: Int, y: Int, z: Int): URL 
       return URL(String.format(Locale.GERMAN, "https:// domain.com/256/%d/%d/%d/image.png", z, x, y))
   

【讨论】:

感谢您的回答。我试过那些。仍然无法正常工作。您使用的是哪个版本的play-services-maps 和你一样。"com.google.android.gms:play-services-maps:17.0.0"。您是否尝试在返回 URL 上设置断点,并评估表达式以查看实际的图像 url?把它放在浏览器中,检查你是否得到 404 错误? 我试过了。网址很好,当我在浏览器中打开网址时,图像也会出现。此外,我还尝试了一个仅使用本地 png 文件的虚拟 tile 提供程序。那也行不通。虽然瓷砖正在生成。我的假设是问题不在于瓷砖提供商。来自这里的代码 - ***.com/questions/21165489/… 你在模拟器上试试这个吗?尝试点击三个点 > Google Play > 更新。 我在我的手机上试用过 - OnePlus5T、Genemotion Emulator API 28 和 Moto G5。没有工作。问题肯定在我的代码中,而不是在设备或播放服务上。问题 - 你是在 addTileOverlay 之后还是之前调用一些代码?【参考方案3】:

我知道现在回答这个问题为时已晚,但我写出了自己的方式,希望对你有用。

我也遇到了这个问题,使用 OSM 标准切片层,我通过从以下位置更改 OSM 切片服务器来解决这个问题:

https://tile.openstreetmap.org/z/x/y.png

到:

https://a.tile.openstreetmap.de/z/x/y.png

您可以在以下链接中查看 OSM 磁贴服务器:

https://wiki.openstreetmap.org/wiki/Tile_servers

【讨论】:

以上是关于自定义图块覆盖在最新的适用于 Android 的 Google Maps SDK 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

MapBox GL Android:来自自定义图块源的离线地图已下载但未使用

适用于 Android 的 Instagram 自定义 URL 方案

使用适用于 Android 应用的自定义适配器将项目动态添加到列表视图

如何覆盖android中的操作栏后退按钮?

适用于 Android 的 Google 地图我的位置自定义按钮

为 Phonegap 构建创建自定义 AdMob 插件(适用于 iOS 和 Android)