2

I'm working on TileOverlay with Google Maps API for Android. Thanks to this post (here) I generated tiles from a png image and I've placed them in the Android assets folder under a "tiles" folder (assets/tiles/myTiles.png). I don't want to upload png tiles online, I want my app to work without Internet. My tiles are named according to this pattern : x-y-zoom.png. Here is my onMapReady:

@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;

    TileProvider tileProvider = new UrlTileProvider(256, 256) {
        @Override
        public URL getTileUrl(int x, int y, int zoom) {
            String url = "file:///android_asset/tiles/" + x + "-" + y + "-" + zoom + ".png";
            try {
                return new URL(url);
            } catch (MalformedURLException e) {
                // ignore
            }
            return null;
        }
    };

    TileOverlay tileOverlay = mMap.addTileOverlay(new TileOverlayOptions().tileProvider(tileProvider));
}

But when I start the app, the map appears but TileOverlay doesn't.

What I tried and found:

  • I tried to log the url String and the returned String points to an existant file.
  • I also tried to replace my url with a well known tile service (http://b.tile.openstreetmap.org/" + zoom + "/" + x + "/" + y + ".png) and this time, TileOverlay appears.

So I think it's the given url that does not work. On other forums (like here) I've understood that URLs beggining with file:///android_asset/ only work with AndroidWebView.

But I found nowhere how to create an URL from an asset file. How can I do that?

remjln
  • 41
  • 4
  • Implement TileProvider and use AssetManager to get an InputStream to then read the byte data, as mentioned here: https://stackoverflow.com/questions/4820816/how-to-get-uri-from-an-asset-file –  May 14 '18 at 16:12
  • thanks it works ! I'm new here, should I post my solution ? – remjln May 14 '18 at 16:32
  • congrats - solutions are good, so post! –  May 14 '18 at 16:35

1 Answers1

1

If someone still needs it, I solved this doing like Andy said:

mMap = googleMap;

TileProvider tileProvider = new TileProvider() {
        @Override
        public Tile getTile(int x, int y, int zoom) {
            try {
                InputStream inputStream = getAssets().open(String.format("tiles/%d_%d_%d.png", zoom, x, y));
                byte[] buffer = new byte[8192];
                int bytesRead;
                ByteArrayOutputStream output = new ByteArrayOutputStream();

                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    output.write(buffer, 0, bytesRead);
                }
                byte file[] = output.toByteArray();

                Tile result = new Tile(256, 256, file);

                return result;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    };

TileOverlay tileOverlay = mMap.addTileOverlay(new TileOverlayOptions().tileProvider(tileProvider));

In my case, I am putting the tiles inside a "tiles" folder on assets. Make sure to change it.