SDK for Android Developer's Guide

Custom Raster Tiles

You can use SDK for Android to enhance maps with custom raster tiles. Custom raster tiles are tile images that you can add to a map to customize it with enhanced information. For example, you may wish to use this feature to add heat maps over a map of New York City. You can store custom raster tile images locally or on a remote server for users to access when they navigate in a map. If the application is set to display custom raster tiles, then tiles are displayed when users view a designated geographical area at a specified zoom level or range of zoom levels.

Dividing a Map and Tile Lookup

To use your own custom raster tile images, you need to have a scheme for dividing your map according to the zoom level and map coordinates and then provide map tiles according to this scheme. Your application must then use this scheme in the implementation of one of the following classes:
  • MapRasterTileSource - Implement this class if you plan to fetch local tile images, create dynamic images, or if you would like to provide your own method of retrieving images from a remote server.
  • UrlMapRasterTileSourceBase - This is a convenience child class of MapRasterTileSource. Implement this if you plan to fetch tile images from a remote server using a URL over HTTP.
Note: Raster tiles can be one of the following supported image types:
  • PNG
  • JPEG
  • BMP

Once a tile source has been implemented you can toggle its display by adding or removing it to the map using Map.addRasterTileSource(MapRasterTileSource) or Map.removeRasterTileSource(MapRasterTileSource).

The MapRasterTileSource Abstract Class

MapRasterTileSource is the common way for you to define your raster tile source. If your application uses local tile images or remote images that require custom server authentication, then you should implement this class by defining hasTile() and getTileWithError() methods. For example:


public class MyTileSource extends MapRasterTileSource {

  @Override
  public boolean hasTile(int x, int y, int zoomLevel) {
    return true;
  }

  @Override
  public TileResult getTileWithError(int x, int y, int zoomLevel) {
    byte[] myImageData = null;
    // perform tile retrieval logic such as server authentication
    // also translate the x, y, and zoomlevel to address an image

    TileResult result = new TileResult(Error.NONE, myImageData);
    return result;
  }
}
Note: Ensure that getTileWithError() returns within a reasonable amount of time. If your operation takes a longer period of time, launch an asynchronous operation and return the TileResult.Error.NOT_READY error code while the operation is in progress.

The UrlMapRasterTileSourceBase Abstract Class

UrlMapRasterTileSourceBase is a child abstract class of MapRasterTileSource that you can use if you plan to fetch tile images from a remote server using image URLs. The following is a sample implementation of UrlMapRasterTileSourceBase. In this example, we use the MapRasterTileSource.MapTileSystemHelper.tileXYToQuadKey() method to address our map tiles. This helper method assumes that we are using a quadtree/quadkey scheme where the map is divided into a quadtree (a tree data structure where each node has exactly four children) with 20 levels. Each level of this map quadtree has (2 x )2 tiles where x represents the floor function value of the current zoom level. So for level 0 there is 1 x 1 = 1 tile, level 1 has 2 x 2 = 4 tiles, level 2 has 4 x 4 = 16 tiles, and level 3.7 has 8 x 8 = 64 tiles—since the floor value of 3.7 is 3.

For more information about the quadkey/quadtree division scheme see the tileXYToQuadKey() API reference.


public class LiveMapRasterTileSource extends UrlMapRasterTileSourceBase {

  private final static String URL_FORMAT =
      "http://1.communitymaptiles.example.org/tilehub/live/map/png/%s";

  public LiveMapRasterTileSource() {
    // We want the tiles placed over everything else
    setOverlayType(MapOverlayType.FOREGROUND_OVERLAY);
    // We don't want the map visible beneath the tiles
    setTransparency(Transparency.OFF);
    // We don't want the tiles visible between these zoom levels
    hideAtZoomRange(12, 20);
    // Do not cache tiles
    setCachingEnabled(false);
  }

  // Implementation of UrlMapRasterTileSourceBase
  public String getUrl(int x, int y, int zoomLevel) {
    String url = null;

    // Utility to map the x, y coordinates easily into an equivalent
    // quadkey at a specified zoomLevel
    String quadKey =
        MapTileSystemHelper.tileXYToQuadKey(x, y, zoomLevel);

    try {
      // Append the quadkey to the URL template to get a real URL
      url = String.format(URL_FORMAT, quadKey);
    } catch (Exception ex) {
      ex.printStackTrace();
    }

    return url;
  }
}

The example above generates a quadkey from the x, y coordinates and the zoom level and appends it to the URL. However, this is server-specific and the method of converting x, y and zoom level to a URL can be done in many ways. Also, it is worth noting that tiles can be cached with setCachingEnabled(true).

Changing the Overlay Rendering Order

You can choose to customize the order raster tiles are rendered in by calling MapRasterTileSource.setOverlayType(MapOverlayType). For example, MapOverlayType.BACKGROUND_OVERLAY and MapOverlayType.BACKGROUND_REPLACEMENT are similar to rendering raster tiles with streets rendered on top. MapOverlayType.FOREGROUND_OVERLAY renders tiles on top of everything on the map.

Caching Tiles

Tiles can be cached to the disk by calling the following:

// Give the tile source a custom prefix so it can be cached on the disk
MapRasterTileSource.setCachePrefix(String cache)

// Give each raster tile file an expiration time in seconds
MapRasterTileSource.setCacheExpiration( int seconds )

If no expiration time is set, then the raster tiles remain on the device. We recommend that both a cache prefix and an expiration time be set.