カスタムマーカーに対応した Xamarin.Forms.GoogleMaps v1.4.0 をリリースしました

Xamarin.Forms.GoogleMaps v1.4.0 をリリースしました。

待望?のカスタムマーカーに対応しました。

image001

カスタムマーカーの使い方

Pin.IconBitmapDescriptorFactory により生成される BitmapDescriptor を設定します。

BitmapDescriptorFactory の3つのファクトリメソッドにより、 「デフォルトマーカーの色を変える」「プラットフォーム毎の画像リソースを使用する」「共通の画像リソースを使用する」 の3つが使用できます。

デフォルトマーカーの色を変える

iOS:GMSMarker.markerImageWithColor, Android:BitmapDescriptorFactory.defaultMarker に対応する、既定のマーカー形状の色のみを変える機能です。

以下のように、 BitmapDescriptorFactory.DefaultMarker(Color) メソッドを使用します。

pin.Icon = BitmapDescriptorFactory.DefaultMarker(Color.Pink);

プラットフォーム毎の画像リソースを使用する

iOS:UIImage.imageNamed, Android:BitmapDescriptorFactory.fromAsset に対応する、プラットフォーム固有の画像リソースを、マーカー画像として使用する機能です。

以下のように、 BitmapDescriptorFactory.FromBundle(string) メソッドを使用します。

pin.Icon = BitmapDescriptorFactory.FromBundle("image01.png");

引数の bundleName は、 同じ名称で 、プラットフォーム毎に次のように用意されている必要があります。

Android の場合

Android側のプロジェクトの Assets ディレクトリ内に image01.png を追加し、 Build Action を ”Android Asset” に設定します。

image001

iOS の場合

iOS側のプロジェクト image01.png を追加し、 Build Action を ”BundleResource” に設定します。

image001

共通の画像リソースを使用する

画像を Stream を直接指定できる、機能です。

以下のように、 BitmapDescriptorFactory.DefaultMarker(Color) メソッドを使用します。

// PCLプロジェクトに EmbeddedResouece として追加した "marker01.png" を読み込んで Stream 化
var assembly = typeof(CustomPinsPage).GetTypeInfo().Assembly;
var stream = assembly.GetManifestResourceStream($"XFGoogleMapSample.marker01.png");

// Stream をマーカーに設定
pin.Icon = BitmapDescriptorFactory.FromStream(stream);

【注意】プラットフォーム毎のマーカーサイズの違い

「プラットフォーム毎の画像リソースを使用する」「共通の画像リソースを使用する」で見られる現象なのですが、iOS と Android では 同じサイズの画像を指定しているのに iOS の方が大きく描画されます

image001

なぜこうなるのか分かりませんが、 Google Maps SDK for iOSGoogle Maps Android API を直接使用した時もこうなるので、両者の仕様というかプラットフォーム自体の仕様なのかも知れません。

特に BitmapDescriptorFactory.FromStream を使用した時には使い勝手が悪いのですが、「ネイティブの Google Maps SDK の機能を共通APIでラップする」のが第一目標なので、とりあえず画像を何も加工しない実装でリリースしました。

何か原因などについてヒントがある方は

に書いてもらえると助かります(日本語で大丈夫です)。

サンプルプログラム

XFGoogleMapSampleCustomPinsPage.xaml.cs でこれらの機能を使用しています。

是非使ってみてください。よければ Github リポジトリ に Star ください。