第 28 章の概要: 位置情報と地図

Note

この本は 2016 年春に発行されて以降、改訂されていません。 多くの情報はまだ価値がありますが、一部の資料は古くなっており、トピックの中にはまったく正しくないものまたは不完全なものもあります。

Xamarin.Forms では、View から派生した Map 要素がサポートされています。 地図の使用に関する特別なプラットフォーム要件のため、これらは別のアセンブリ (Xamarin.Forms.Maps) に実装され、別の名前空間 (Xamarin.Forms.Maps) が使用されています。

地理座標系

地理座標系では、地球のような球体 (またはほぼ球体) の物体上の位置が特定されます。 座標は、角度で表された "緯度" と "経度" の両方によって構成されます。

equator と呼ばれる大きな円は、地球の軸が概念的に伸びていく 2 つの極の中間にあります。

緯線と緯度

地球の中心点から赤道の北または南に向かってある角度を測ると、"緯線" と呼ばれる等しい緯度の線ができます。 これらの範囲は、赤道の 0 度から、北極と南極の 90 度までです。 慣例により、赤道より北の緯度は正の値、赤道より南は負の値になります。

経度と経線

北極から南極までを結ぶ大きな半円は、等しい経度の線です。"経線" とも呼ばれます。 これらは、英国のグリニッジ子午線を基準としています。 慣例により、グリニッジ子午線より東の経度は 0 度から 180 度までの正の値、グリニッジ子午線より西の経度は 0 度から -180 度までの負の値になります。

正距円筒図法

地球を平らな地図にすると、必ずゆがみが発生します。 緯度と経度の線がすべて直線であり、緯度および経度の角度差が同じなら対応する地図上の距離も同じになる場合、その結果は "正距円筒図法" になります。 この地図では、極に近い領域でゆがみが発生します。水平方向に拡張されるためです。

メルカトル図法

よく使われる "メルカトル図法" では、これらの領域を垂直方向にも拡張することによって、水平方向の拡張を補おうとします。 これにより、極に近い領域が実際よりもかなり大きく見える地図が生成されますが、局所的な領域は実際の領域と極めて正確に一致します。

地図サービスとタイル

地図サービスでは、Web Mercator と呼ばれるメルカトル図法のバリエーションの 1 つが使用されます。 地図サービスは、位置とズーム レベルに基づいて、クライアントにビットマップ タイルを提供します。

ユーザーの位置情報を取得する

Xamarin.FormsMap クラスには、ユーザーの地理的な位置情報を取得する機能は含まれていません。しかし、これは地図を操作するときによく必要になるので、依存関係サービスで処理する必要があります。

Note

Xamarin.Forms アプリケーションでは、代わりに、Xamarin.Essentials に含まれる Geolocation クラスを使用できます。

位置情報トラッカー API

Xamarin.FormsBook.Platform ソリューションには、位置情報トラッカー API のコードが含まれています。 GeographicLocation 構造体により、緯度と経度がカプセル化されます。 ILocationTracker インターフェイスでは、位置情報トラッカーを開始および一時停止する 2 つのメソッドと、新しい位置情報が利用可能になったときのイベントが定義されています。

iOS 位置情報マネージャー

ILocationTracker の iOS での実装は、iOS の CLLocationManager を使用する LocationTracker クラスです。

Android 位置情報マネージャー

ILocationTracker の Android での実装は、Android の LocationManager クラスを使用する LocationTracker クラスです。

UWP geo ロケーター

ILocationTracker のユニバーサル Windows プラットフォームでの実装は、UWP Geolocator を使用する LocationTracker クラスです。

スマートフォンの位置情報を表示する

WhereAmI サンプルでは、位置情報トラッカーを使用して、スマートフォンの位置情報が、テキストと正距円筒図法の地図の両方に表示されます。

必要なオーバーヘッド

WhereAmI で位置情報トラッカーを使用するためには、いくらかのオーバーヘッドが必要です。 まず、WhereAmI ソリューション内のすべてのプロジェクトが、Xamarin.FormsBook.Platform 内の対応するプロジェクトに対する参照を持っている必要があります。また、各 WhereAmI プロジェクトで Toolkit.Init メソッドを呼び出す必要があります。

位置情報のアクセス許可という形で、さらにいくらかのプラットフォーム固有のオーバーヘッドが必要です。

iOS の位置情報のアクセス許可

iOS の場合、info.plist ファイルには、ユーザーにそのユーザーの位置情報の取得を許可するように求める、質問のテキストを含む項目が含まれている必要があります。

Android 位置情報のアクセス許可

ユーザーの位置情報を取得する Android アプリケーションは、AndroidManifest.xml ファイルの ACCESS_FILE_LOCATION アクセス許可を持っている必要があります。

UWP 位置情報のアクセス許可

ユニバーサル Windows プラットフォーム アプリケーションの場合は、Package.appxmanifest ファイルで location デバイス機能がマークされている必要があります。

Xamarin.Forms.Maps の使用

Map クラスの使用には、いくつかの要件が関係しています。

NuGet パッケージ

Xamarin.Forms.Maps NuGet ライブラリをアプリケーション ソリューションに追加する必要があります。 バージョン番号は、現在インストールされている Xamarin.Forms パッケージと同じである必要があります。

Maps パッケージの初期化

アプリケーション プロジェクトでは、Xamarin.Forms.Forms.Init の呼び出しを行った後、Xamarin.FormsMaps.Init メソッドを呼び出す必要があります。

地図サービスの有効化

Map ではユーザーの位置情報を取得できるため、アプリケーションでは、この章で前に説明した方法で、ユーザーのアクセス許可を取得する必要があります。

iOS の地図の有効化

Map を使用する iOS アプリケーションでは、info.plist ファイルに 2 行が必要です。

Android の地図の有効化

Google Map サービスを使用するには、承認キーが必要です。 このキーは、AndroidManifest.xml ファイルに挿入されます。 さらに、AndroidManifest.xml ファイルには、ユーザーの位置情報の取得に関連する manifest タグが必要です。

UWP の地図の有効化

ユニバーサル Windows プラットフォーム アプリケーションでは、Bing Maps を使用するための承認キーが必要です。 このキーは、引数として Xamarin.FormsMaps.Init メソッドに渡されます。 また、位置情報サービスに対してもアプリケーションを有効にする必要があります。

簡素なマップ

MapDemos サンプルは、MapsDemoHomePage.xaml と、さまざまなデモンストレーション プログラムへの移動を可能にする MapsDemoHomePage.xaml.cs 分離コード ファイルで構成されています。

BasicMapPage.xaml ファイルでは、Map ビューを表示する方法が示されています。 既定ではローマ市が表示されるようになっていますが、ユーザーが地図を操作することが可能です。

水平方向および垂直方向のスクロール機能を無効にするには、HasScrollEnabled プロパティを false に設定します。 ズーム機能を無効にするには、HasZoomEnabledfalse に設定します。 これらのプロパティは、すべてのプラットフォームでは動作しない可能性があります。

ストリートと地形

3 つのメンバーを含む列挙型 MapType 型である、Map のプロパティ MapType を設定することで、さまざまな種類の地図を表示することができます。

MapTypesPage.xaml ファイルでは、ラジオ ボタンを使用してマップの種類を選択する方法が示されています。 ここでは、Xamarin.FormsBook.Toolkit ライブラリの RadioButtonManager クラスと、MapTypeRadioButton.xaml ファイルに基づくクラスが使用されています。

地図の座標

プログラムでは、VisibleRegion プロパティを通じて Map が表示している現在の領域を取得することができます。 このプロパティは、バインド可能なプロパティによってサポートされて "いません"。これが変更されたときに通知するメカニズムは存在しないため、このプロパティを監視する必要があるプログラムでは、おそらく、その目的のためにタイマーを使用する必要があります。

VisibleRegionMapSpan 型です。これは、4 つの読み取り専用プロパティを持つクラスです。

PositionDistance は両方とも構造体です。 Position では、Position コンストラクターによって設定される 2 つの読み取り専用プロパティが定義されます。

Distance の目的は、メートル法とヤード ポンド法の間の変換を行うことで、単位に依存しない距離を提供することです。 Distance 値は、いくつかの方法で作成できます。

その値は、次の 3 つのプロパティから利用できます。

MapCoordinatesPage.xaml ファイルには、MapSpan 情報を表示するための Label 要素がいくつか含まれています。 MapCoordinatesPage.xaml.cs 分離コード ファイルでは、ユーザーが地図を操作したときに情報を最新の状態に保つために、タイマーが使用されています。

Position の拡張機能

Xamarin.FormsBook.Toolkit.Maps という名前の、この書籍用の新しいライブラリには、地図に固有で、プラットフォームに依存しない型が含まれています。 PositionExtensions クラスには、Position 用の ToString メソッドと、2 つの Position 値の間の距離を計算するメソッドが含まれています。

初期位置情報を設定する

MapMoveToRegion メソッドを呼び出して、地図上の位置情報とズーム レベルをプログラムで設定することができます。 この引数は MapSpan 型です。 MapSpan オブジェクトは、次のいずれかを使用して作成できます。

メソッド ClampLatitude または WithZoom を使用して、既存のものから新しい MapSpan を作成することもできます。

WyomingPage.xaml ファイルと WyomingPage.xaml.cs 分離コード ファイルでは、MoveToRegion メソッドを使用してワイオミング州を表示する方法が示されています。

または、MapSpan オブジェクトを指定する Map コンストラクターを使用して、地図の位置情報を初期化することもできます。 XamarinHQPage.xaml ファイルでは、これを完全に XAML で実行して、サンフランシスコにある Xamarin 本社を表示する方法が示されています。

動的ズーム

Slider を使用すると、地図を動的にズームできます。 RadiusZoomPage.xaml ファイルと RadiusZoomPage.xaml.cs 分離コード ファイルでは、Slider 値に基づいて地図の半径を変更する方法が示されています。

LongitudeZoomPage.xaml ファイルと LongitudeZoomPage.xaml.cs 分離コード ファイルでは、Android 上でよりうまく機能する別の方法が示されています。ただし、どちらの方法も Windows プラットフォーム上では適切に機能しません。

スマートフォンの位置情報

ShowLocationPage.xaml ファイルで示されているように、MapIsShowingUser プロパティは、各プラットフォーム上で動作が少し異なります。

  • iOS では、青い点がスマートフォンの位置情報を示しますが、そこまで手動で移動する必要があります
  • Android では、押すと地図をスマートフォンの位置情報に移動させるアイコンが表示されます
  • UWP は iOS に似ていますが、その位置情報に自動的に移動する場合があります

MapDemos プロジェクトでは、Android のアプローチを模倣しようとしています。そのために、MyLocationButton.xaml ファイルと MyLocationButton.xaml.cs 分離コード ファイルに基づいて、最初にアイコン ベースのボタンを定義します。

GoToLocationPage.xaml ファイルと GoToLocationPage.xaml.cs 分離コード ファイルでは、このボタンを使用してスマートフォンの位置情報に移動します。

Pins と科学博物館

最後に、Map クラスでは IList<Pin> 型の Pins プロパティが定義されます。 Pin クラスでは、4 つのプロパティが定義されます。

  • string 型の Label (必須プロパティです)
  • string 型の Address (省略可能な人間が判読できる住所です)
  • Position 型の Position (地図上にピンが表示される場所を示します)
  • PinType 型 (列挙型) の Type (使用されません)

MapDemos プロジェクトには、米国にある科学博物館を一覧表示した ScienceMuseums.xml ファイルと、このデータを逆シリアル化するための Locations クラスと Site クラスが含まれています。

ScienceMuseumsPage.xaml ファイルと ScienceMuseumsPage.xaml.cs 分離コード ファイルでは、地図内のこれらの科学博物館に対してピンが表示されます。 ユーザーがピンをタップすると、その博物館の住所と Web サイトが表示されます。

2 点間の距離

PositionExtensions クラスには、2 つの地理的な場所の距離を簡単に計算する DistanceTo メソッドが含まれています。

これは、LocalMuseumsPage.xaml ファイルと LocalMuseumsPage.xaml.cs 分離コード ファイルで、ユーザーの位置情報から博物館までの距離も表示するために使用されています。

地域の博物館ページのトリプル スクリーンショット

また、このプログラムでは、地図の位置情報に基づいてピンの数を動的に制限する方法も示されています。

ジオコーディングと逆ジオコーディング

Xamarin.Forms.Maps アセンブリには、Geocoder クラスも含まれています。これには、テキストの住所を可能な 0 個以上の地理的位置に変換する GetPositionsForAddressAsync メソッドと、逆方向に変換する別の GetAddressesForPositionAsync メソッドが含まれています。

GeocoderRoundTrip.xaml ファイルと GeocoderRoundTrip.xaml.cs 分離コード ファイルでは、この機能が示されています。