読者です 読者をやめる 読者になる 読者になる

プログラムの事とか

お約束ですが「掲載内容は私個人の見解です」

Xamarin.Androidで地図にTileを追加したりしてみる

f:id:puni-o:20160422163818j:plain

puni-o.hatenablog.com

puni-o.hatenablog.com

puni-o.hatenablog.com

puni-o.hatenablog.com

のXamarin.Android版です。 最後にしたのは環境とか下準備が面倒だからです。面倒なので下準備はググってください。

f:id:puni-o:20160422164711p:plain

準備完了

Open Street Mapを追加する

追加してみます。

class CustomTileProvider : UrlTileProvider
{
    public CustomTileProvider() : base(256, 256) { }
    public override URL GetTileUrl(int x, int y, int zoom) =>
        new URL($"http://tile.openstreetmap.org/{zoom}/{x}/{y}.png");
}

UrlTileProviderを継承してGetTileUrlをオーバーライドします。

他とほとんど変わりませんね。

あとは追加。

public void OnMapReady(GoogleMap googleMap)
{
    googleMap.AddTileOverlay(new TileOverlayOptions().InvokeTileProvider(new CustomTileProvider()));
}

OnMapReadyがどこから呼ばれるのかはググればわかるんじゃないでしょうか。

実行するとOpen Street Mapが地図の上に出ます。(スクショは割愛)

既定の地図を変更する

というか、今回もデフォルトの地図を消します。

googleMap.MapType = GoogleMap.MapTypeNone;

これでデフォルトがなくなります。

自分で描いたタイルの追加

ITileProviderを実装したクラスを作ります。

class OwnDrawTileProvider : Java.Lang.Object, ITileProvider
{
    public Tile GetTile(int xValue, int yValue, int zoom)
    {
        var a = 0x80;
        var r = ((xValue + yValue) % 3) == 0 ? 0xFF : 0;
        var g = ((xValue + yValue + 1) % 3) == 0 ? 0xFF : 0;
        var b = ((xValue + yValue + 2) % 3) == 0 ? 0xFF : 0;

        using (var bitmap = Bitmap.CreateBitmap(256, 256, Bitmap.Config.Argb8888))
        using (var canvas = new Canvas(bitmap))
        using (var fill = new Paint())
        using (var stream = new MemoryStream())
        {
            fill.SetStyle(Paint.Style.Fill);
            fill.SetARGB(a, r, g, b);
            canvas.DrawRect(0, 0, 256, 256, fill);

            bitmap.Compress(Bitmap.CompressFormat.Png, 100, stream);
            return new Tile(256, 256, stream.ToArray());
        }
    }
}

やっていることは見ればわかりますね。いつも通りです。

後はこのクラスを追加するだけ。

public void OnMapReady(GoogleMap googleMap)
{
    googleMap.AddTileOverlay(new TileOverlayOptions().InvokeTileProvider(new OwnDrawTileProvider()));
}

できました。(スクショ割愛)

おわり

とりあえずいろんなプラットフォームの地図にTileを追加してみました。 TMSの仕組みがわかっていればどのプラットフォームでもやることは大体想像できる、ということが分かったと思います。 (ここまで書いてきた事がベストプラクティスではないかもしれませんが、まぁとりあえず動くからいいんじゃないでしょうか)

地図ネタはもうちょっとありますが、それはまたいつかやるかもかも・・・ (誰の役にも立たないSilverlightバッドノウハウとか)