第 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
に設定します。 ズーム機能を無効にするには、HasZoomEnabled
を false
に設定します。 これらのプロパティは、すべてのプラットフォームでは動作しない可能性があります。
ストリートと地形
3 つのメンバーを含む列挙型 MapType
型である、Map
のプロパティ MapType
を設定することで、さまざまな種類の地図を表示することができます。
MapTypesPage.xaml ファイルでは、ラジオ ボタンを使用してマップの種類を選択する方法が示されています。 ここでは、Xamarin.FormsBook.Toolkit ライブラリの RadioButtonManager
クラスと、MapTypeRadioButton.xaml ファイルに基づくクラスが使用されています。
地図の座標
プログラムでは、VisibleRegion
プロパティを通じて Map
が表示している現在の領域を取得することができます。 このプロパティは、バインド可能なプロパティによってサポートされて "いません"。これが変更されたときに通知するメカニズムは存在しないため、このプロパティを監視する必要があるプログラムでは、おそらく、その目的のためにタイマーを使用する必要があります。
VisibleRegion
は MapSpan
型です。これは、4 つの読み取り専用プロパティを持つクラスです。
Center
(Position
型)double
型のLatitudeDegrees
。地図の表示領域の高さを示しますdouble
型のLongitudeDegrees
。地図の表示領域の幅を示しますDistance
型のRadius
。地図上に表示される最大の円形領域のサイズを示します
Position
と Distance
は両方とも構造体です。 Position
では、Position
コンストラクターによって設定される 2 つの読み取り専用プロパティが定義されます。
Distance
の目的は、メートル法とヤード ポンド法の間の変換を行うことで、単位に依存しない距離を提供することです。 Distance
値は、いくつかの方法で作成できます。
Distance
コンストラクター (メートル法の距離を指定)Distance.FromMeters
静的メソッドDistance.FromKilometers
静的メソッドDistance.FromMiles
静的メソッド
その値は、次の 3 つのプロパティから利用できます。
Meters
(double
型)Kilometers
(double
型)Miles
(double
型)
MapCoordinatesPage.xaml ファイルには、MapSpan
情報を表示するための Label
要素がいくつか含まれています。 MapCoordinatesPage.xaml.cs 分離コード ファイルでは、ユーザーが地図を操作したときに情報を最新の状態に保つために、タイマーが使用されています。
Position の拡張機能
Xamarin.FormsBook.Toolkit.Maps という名前の、この書籍用の新しいライブラリには、地図に固有で、プラットフォームに依存しない型が含まれています。 PositionExtensions
クラスには、Position
用の ToString
メソッドと、2 つの Position
値の間の距離を計算するメソッドが含まれています。
初期位置情報を設定する
Map
の MoveToRegion
メソッドを呼び出して、地図上の位置情報とズーム レベルをプログラムで設定することができます。 この引数は MapSpan
型です。 MapSpan
オブジェクトは、次のいずれかを使用して作成できます。
MapSpan
コンストラクター (Position
、緯度と経度のスパンを指定)MapSpan.FromCenterAndRadius
(Position
と半径を指定)
メソッド 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 ファイルで示されているように、Map
の IsShowingUser
プロパティは、各プラットフォーム上で動作が少し異なります。
- 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 分離コード ファイルでは、この機能が示されています。