0

I'm trying to display OpenCycleMaps inside google maps sdk for android using addTileOverlay and a custom tile provider but its not working in the latest version of the SDK.

This is the version of the SDK I'm using -

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

And this is the code I'm using to display custom tiles. Here I'm setting the map to none and then showing custom tiles instead -

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

This is the custom tile provider class -

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

To make sure the problem was not in my code, I tried the same with this^ code in https://github.com/googlemaps/android-samples/tree/master/ApiDemos/kotlin and since they have not upgraded to androidX and are still using play-services-maps:11.8.0 it was working on there; custom tiles were being displayed. On upgrading that same code to use the latest maps SDK it stopped working.

vepzfe
  • 4,217
  • 5
  • 26
  • 46

3 Answers3

1

The problem was not in the TileProvider or the Google Maps component at all. The issue was with the tile url. The first issue in that was that the url was http, requests to which were failing. The second issue in that was that a.tile.opencyclemap.org was somehow not resolving on Android. So I looked up OSM wiki and found this url for opencyclemaps - http://tile.thunderforest.com/cycle/${z}/${x}/${y}.png which perfectly works.

This is the working code -

mapType = GoogleMap.MAP_TYPE_NONE
val mTileProvider = MyUrlTileProvider(256, 256, "https://tile.thunderforest.com/cycle/{z}/{x}/{y}.png.png")
addTileOverlay(TileOverlayOptions().tileProvider(mTileProvider))
vepzfe
  • 4,217
  • 5
  • 26
  • 46
  • Think that one does not even need any third party provider, but can style it; once answered similar transport layer question, but I'm on a phone right now. I mean, the difference should become more obvious, when trying to pass on the route into navigation. – Martin Zeitler Oct 15 '19 at 16:24
  • What do you mean by 3rd party provider? OpenCycleMap is officially owned and developed by Thunderforest Maps. – vepzfe Oct 16 '19 at 05:01
  • 3rd party provider is any entity who is not Google... and smooth integration with the "Navigation" app might only work with Google Maps transport layers; else one like has to lookup the same route from two routing providers. It always depends on the application; eg. MapQuest is good for routing, too because it does not have certain limits as Google has (or had, before making it a paid API). The API I once needed there was only for corporate customers, costed alike 7 grand per month; with the new pricing scheme this might have changed. Thunderforest Maps might not offer any SLA. – Martin Zeitler Oct 16 '19 at 05:44
  • Sorry but the question is not about routing at all or the need of these map tiles for navigation. All I wanted to know was why custom map tiles were not working for me; which got resolved. Regarding your first comment, Google maps can be styled, but it does not show data like cycle routes etc which can be obtained only through external map tile providers. Hence this is required. Thanks though. – vepzfe Oct 16 '19 at 05:54
  • I came across a similiar problems. It turns out sometimes OSM or Mapbox servers might be down or perhaps block you for a while, that's presumably why thunderforest worked when other tile providers didn't. If this happens (e.g. it works on api below 29 but not on 29, be patient). – TinaFrieda Feb 09 '20 at 02:36
0

It works ok for me.

  1. Try to add .visible(true) to .tileProvider(mTileProvider)).visible(true)
  2. Make better URL in TileProvider:
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))
   }
}
Simon
  • 1,657
  • 11
  • 16
  • Thank you for your answer. I tried those. Still not working though. Which version of the `play-services-maps` are you using? – vepzfe Oct 15 '19 at 12:39
  • Same as you."com.google.android.gms:play-services-maps:17.0.0". Have you tried to put a breakpoint on the return URL, and evaluate the expression to see the actual image url? Put it in browser and check if you get 404 error maybe? – Simon Oct 15 '19 at 13:05
  • I tried that. The url is fine, the image is also coming when I open the url in the browser. Additionally I also tried a dummy tile provider which just uses a local png file. That too is not working. The tile is getting generated though. My assumption from this is that the problem is not with the tile provider. Code from here - https://stackoverflow.com/questions/21165489/a-dummy-map-tile-provider-not-working-gettile-not-being-called – vepzfe Oct 15 '19 at 13:08
  • Are you trying this on emulator? Try to click three dots > Google Play > Update. – Simon Oct 15 '19 at 13:15
  • 1
    I tried it on my phone - OnePlus5T, Genemotion Emulator API 28 and Moto G5. Working on none of them. The problem is certainly in my code and not on the device or play-services. Question - are you calling some code after `addTileOverlay`, or before it? – vepzfe Oct 15 '19 at 13:20
  • Just map.clear() before I start loading the overlay. – Simon Oct 15 '19 at 13:23
  • I tried that. Weirdly, without me having added any code, the dummy tile provider is suddenly now working. UrlTileProvider still not working though :/. – vepzfe Oct 15 '19 at 13:28
  • I noticed that you're passing "time" to the TileProvider. What is the use of that? – vepzfe Oct 15 '19 at 13:43
0

I know it is too late to answer this question, but I write my way and hope to be useful.

I had this issue too, with OSM standard tile layer and I solve this problem by changing OSM tile server from:

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

to:

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

You can see OSM tile servers in below link:

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