タイル オーバーレイ

タイル オーバーレイ(タイルレイヤとも呼ばれる)は、基本地図タイルの上に重ねて表示される画像のコレクションです。

コードサンプル

GitHub の ApiDemos リポジトリには、タイル オーバーレイの機能を示すサンプルが含まれています。

はじめに

TileOverlay は、基本地図タイルの上に重ねて追加される画像のセットを定義します。

サポートするズームレベルごとにタイルを提供する必要があります。 複数のズームレベルに十分な数のタイルがある場合は、マップ全体で Google のマップデータを補うことができます。

タイル オーバーレイは、大きい画像をマップに追加する場合に役立ちます。これは通常、広い地理的領域が対象です。地面オーバーレイは、地図上のいずれかの領域に 1 つの画像を固定したい場合に役立ちます。

透過的なタイル オーバーレイを使用して、追加の対象物をマップに追加することもできます。そのためには、プログラムでタイル オーバーレイに透明度係数を設定するか、透過タイル画像を指定します。

タイル座標とズームレベル

Google Maps API は、各ズームレベルの画像を、グリッドに配置された一連の正方形のマップタイルに分割します。マップが新しい場所や新しいズームレベルに移動すると、Maps API は必要なタイルを判別し、この情報を、取得する一連のタイルに変換します。

座標(0,0)のタイルは常にマップの北西隅にあり、x 値は西から東へと増分し、y 値は北から南へと増分します。タイルは、この原点からの x,y 座標を使用してインデックスが付けられます。

ズームレベル 0 では、全世界が 1 つのタイルでレンダリングされます。各ズームレベルは、2 の倍数で倍率が増大します。したがって、ズームレベルが 1 の場合、マップは 2x2 グリッドのタイルとしてレンダリングされ、ズームレベルが 2 の場合は 4x4 グリッド、ズームレベルが 3 の場合は 8x8 グリッド、というように続きます。

たとえば、ズームレベル 2 では地球が 16 枚のタイルに分割されます。各タイルは x、y、zoom の一意の組み合わせにより参照できます。

タイルレイヤの画像を作成する場合、サポートするズームレベルごとに、各タイルの画像を作成する必要があります。タイルを表示するとき、Google マップでは 256 dp(デバイスに依存しないピクセル)が使用されます。高解像度のデバイスでは、dpi の高いタイル(512x512 px)を返すことをおすすめします。異なる画面サイズや密度のサポートについては、Android デベロッパー ドキュメントをご覧ください。

注: カメラでサポートされるズームレベルはさまざまな要因によって決まり、タイルでサポートされるズームレベルとは関係ありません。

  1. GoogleMap.getMaxZoomLevel() は、現在のカメラ位置で使用可能な最大のズームレベルを返します。このとき、現在使用されているマップタイプが考慮されます。たとえば、衛星マップや地形マップは、基本地図タイルよりも最大ズームレベルが低いことがあります。
  2. GoogleMap.getMinZoomLevel() は、最小ズームレベルを返します。最大ズームレベルとは異なり、これはすべての場所で同じですが、デバイスやマップサイズによって異なる場合があります。

タイル オーバーレイを追加する

タイル オーバーレイを作成するための最も単純かつ一般的な方法は、該当するタイル画像を指す URL を指定することです。UrlTileProvider は、URL に基づいて画像タイルを提供する TileProvider の部分実装です。このクラスでは、すべての画像の寸法が同じである必要があります。

UrlTileProvider.getTileUrl() の実装が必要になります。これはタイル座標(x、y、zoom)を受け入れ、タイルに使用される画像を指す URL を返します。指定された x、y、zoom にタイルがない場合、このメソッドは null を返します。URL は、ウェブリソース、Android アセット、またはローカル ディスク上のファイルを指すことができます。

サポートするすべての x,y 座標とズームレベルに対して定義されたタイル画像のストックをサーバーでセットアップします。次にタイル オーバーレイを追加します。

  1. タイル画像を提供する UrlTileProvider を定義します。
  2. 各タイル画像の URL を作成するために getTileUrl() を上書きします。
  3. 関連するオプションを指定して、TileOverlayOptions オブジェクトを提供します。
    • fadeIn: ブール値。タイルがフェードインするかどうかを指定します。デフォルト値は true です。タイル オーバーレイをすばやく切り替える場合は、フェードインを無効にすると役立ちます。透明度とフェードインの関係については、下記の透明度のセクションを参照してください。
    • tileProvider: このオーバーレイに使用する TileProvider
    • transparency: 浮動小数点数。タイル画像の透明度係数を設定します。この値は [0.0f, 1.0f] の範囲である必要があります。ここで、0.0f は完全な不透明(デフォルト)を意味し、1.0f は完全な透明を意味します。コードサンプルおよび透明度とフェードインの関係については、下記の透明度のセクションを参照してください。
    • visible: ブール値。タイル オーバーレイの可視性を指定します。非表示のタイル オーバーレイ(値が false)はマップに描画されませんが、その他すべてのプロパティを保持します。デフォルト値は true です。
    • zIndex: 他のオーバーレイに対する、タイル オーバーレイの描画順序を決定します。他のオーバーレイには、地面オーバーレイ円、ポリライン、ポリゴンなどが含まれます。より高い z インデックスを持つオーバーレイが、低い z インデックスを持つオーバーレイより上に重ねて描画されます。z インデックスが同じオーバーレイの順序は任意です。デフォルトの z インデックスは 0 です。なお、マーカーは、他のオーバーレイの z インデックスに関係なく、常に他のオーバーレイの上に描画されます。
  4. GoogleMap.addTileOverlay() を呼び出して、マップにオーバーレイを追加します。

Java

private GoogleMap map;

TileProvider tileProvider = new UrlTileProvider(256, 256) {

    @Override
    public URL getTileUrl(int x, int y, int zoom) {

        /* Define the URL pattern for the tile images */
        String s = String.format("http://my.image.server/images/%d/%d/%d.png", zoom, x, y);

        if (!checkTileExists(x, y, zoom)) {
            return null;
        }

        try {
            return new URL(s);
        } catch (MalformedURLException e) {
            throw new AssertionError(e);
        }
    }

    /*
     * Check that the tile server supports the requested x, y and zoom.
     * Complete this stub according to the tile range you support.
     * If you support a limited range of tiles at different zoom levels, then you
     * need to define the supported x, y range at each zoom level.
     */
    private boolean checkTileExists(int x, int y, int zoom) {
        int minZoom = 12;
        int maxZoom = 16;

        return (zoom >= minZoom && zoom <= maxZoom);
    }
};

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

Kotlin

private lateinit var map: GoogleMap

var tileProvider: TileProvider = object : UrlTileProvider(256, 256) {
    override fun getTileUrl(x: Int, y: Int, zoom: Int): URL? {

        /* Define the URL pattern for the tile images */
        val url = "http://my.image.server/images/$zoom/$x/$y.png"
        return if (!checkTileExists(x, y, zoom)) {
            null
        } else try {
            URL(url)
        } catch (e: MalformedURLException) {
            throw AssertionError(e)
        }
    }

    /*
     * Check that the tile server supports the requested x, y and zoom.
     * Complete this stub according to the tile range you support.
     * If you support a limited range of tiles at different zoom levels, then you
     * need to define the supported x, y range at each zoom level.
     */
    private fun checkTileExists(x: Int, y: Int, zoom: Int): Boolean {
        val minZoom = 12
        val maxZoom = 16
        return zoom in minZoom..maxZoom
    }
}

val tileOverlay = map.addTileOverlay(
    TileOverlayOptions()
        .tileProvider(tileProvider)
)
      

UrlTileProvider の動作の例を見るには、Google Play サービス SDK に付属しているサンプルコードTileOverlayDemoActivity をご覧ください。

タイル オーバーレイの透明度を設定する

マップの上に透過タイルを重ねると、ユーザーには重ねたタイルの下にある基本地図が見えるため便利です。これを行うには、独自の透過タイルを指定するか、プログラムでタイル オーバーレイの透明度係数を設定します。

次のコードサンプルは、タイル オーバーレイの透明度を 0.5f0.0f の間で切り替えます。

Java

private TileOverlay tileOverlayTransparent;

@Override
public void onMapReady(GoogleMap map) {
    tileOverlayTransparent = map.addTileOverlay(new TileOverlayOptions()
        .tileProvider(new UrlTileProvider(256, 256) {
            // ...
        })
        .transparency(0.5f));
}

// Switch between 0.0f and 0.5f transparency.
public void toggleTileOverlayTransparency() {
    if (tileOverlayTransparent != null) {
        tileOverlayTransparent.setTransparency(0.5f - tileOverlayTransparent.getTransparency());
    }
}
      

Kotlin

private var tileOverlayTransparent: TileOverlay? = null

override fun onMapReady(map: GoogleMap) {
    tileOverlayTransparent = map.addTileOverlay(
        TileOverlayOptions()
            .tileProvider(object : UrlTileProvider(256, 256) {
                // ...
            })
            .transparency(0.5f)
    )
}

// Switch between 0.0f and 0.5f transparency.
fun toggleTileOverlayTransparency() {
    tileOverlayTransparent?.let {
        it.transparency = 0.5f - it.transparency
    }
}
      

透明度は、タイル画像のアルファ チャンネル乗数として実装します。タイル オーバーレイの透明度を設定するには、上記のサンプルで示すように transparency[0.0f, 1.0f] の範囲の TileOverlayOptions オブジェクトを指定します。値 0.0f は、タイル オーバーレイが完全に不透明であることを意味し、1.0f は完全に透明であることを意味します。デフォルト値は 0.0f(不透明)です。

TileOverlay.getTransparency() を呼び出すことで、オーバーレイの透明度にアクセスできます。また、TileOverlay.setTransparency() を呼び出すことで透明度を変更できます。

透明度、アニメーション、フェードイン

透明度が変更されるときのアニメーションはありません。transparency オプションは、fadeIn オプションと連携して動作します。

フェードインによって、タイルのロード時に透明度にアニメーション効果を適用できます。透明度の値を設定した場合、タイルは完全に透明な状態から定義された透明度値までフェードインします。フェードインの間に透明度を変更すると、新しいターゲット透明度に達するまでアニメーションが続行します。

タイル オーバーレイを削除する

TileOverlay.remove() メソッドを使って、タイル オーバーレイを削除できます。

Java

tileOverlay.remove();
      

Kotlin

tileOverlay.remove()
      

古いタイルを消去する

タイル オーバーレイにより提供されたタイルが「古く」なったら、clearTileCache() を呼び出して強制的に更新できます。これを呼び出すと、このオーバーレイ上のすべてのタイルがリロードされます。たとえば、TileProvider により提供されたタイルが変更された場合、変更後に clearTileCache() を呼び出して、以前のタイルがレンダリングされないようにする必要があります。

Java

tileOverlay.clearTileCache();
      

Kotlin

tileOverlay.clearTileCache()