Flutter je blogový článek představující funkce použitelné pro vývoj mapových aplikací. Tento článek se zaměřuje na vyhledávání adres. Implementujeme dvě funkce: přesun mapy na zadanou adresu a zobrazení adresy místa, na které uživatel klikne na mapě. 2 funkce. V tomto článku použijeme Flutter mapové SDK (ArcGIS Maps SDK for Flutter) a ukážeme, jak tyto funkce implementovat.
Ukázkový kód je k dispozici na GitHubu , takže si jej můžete ihned stáhnout a vyzkoušet. Návod k spuštění aplikace najdete v README に記載しています。サンプルを実行するために、API キーの取得 (無償) が必要になります。
地図 SDK の導入からマップ表示までの方法は「Flutter で地図アプリを作成してみよう!」のブログ記事をご覧ください。この記事では、住所検索の機能にフォーカスして紹介します。
住所検索
住所検索機能を使用するには、LocatorTask クラスを使用します。LocatorTask には、大きく分けて、以下の 2 つの機能が提供されています。
ジオコーディング機能の実装
まずは、住所文字列から該当する場所を検索するジオコーディング機能を実装していきます。
1. 「Flutter で地図アプリを作成してみよう!」のブログ記事の手順 6 で、マップビュー コントローラーに作成したマップを設定してマップの表示までできたら、_MyHomePageState クラスの最初で、LocatorTask.withUri コンストラクターを使用して LocatorTask を作成します。
class _MyHomePageState extends State<MyHomePage> {
// 追加
//ジオコードサービスの URL を指定して、ジオコーディング用のタスクを作成します。
final _locatorTask = LocatorTask.withUri(
Uri.parse(
'https://geocode-api.arcgis.com/arcgis/rest/services/World/GeocodeServer',
),
);
・・・
ジオコードサービスには、ArcGIS Location Platform のサービスを使用します。住所検索(ジオコーディング/リバースジオコーディング)は、毎月 20,000 回まで無償で利用できます。
2. 続いて、ジオコーディングに使用する住所を入力するためのテキスト入力フォームを作成します。テキスト入力フォームには、Flutter の TextField ウィジェットを使用します。_MyHomePageState クラスの最初で、TextField ウィジェットに設定する _textEditingController と _searchFocusNode 変数を作成します。TextEditingController は、初期状態で表示されるテキストの設定と現在のテキストの取得に使用し、FocusNode はウィジェットのフォーカス状態を管理するのに使用します。
class _MyHomePageState extends State<MyHomePage> {
// 追加
final _textEditingController = TextEditingController(text: '東京都千代田区平河町2-7-1');
final _searchFocusNode = FocusNode();
・・・
3. 続いて Widget build() の Column ウィジェット内にある ArcGISMapView ウィジェットの前に TextField ウィジェットを追加します。
mainAxisAlignment: MainAxisAlignment.center,
children: [
//追加
TextField(
focusNode: _searchFocusNode,
controller: _textEditingController,
decoration: InputDecoration(
hintText: '住所を入力...',
prefixIcon: const Icon(Icons.search),
suffixIcon: IconButton(
onPressed: dismissSearch,
icon: const Icon(Icons.clear),
),
),
onSubmitted: onSearchSubmitted,
),
Expanded(
// ウィジェット ツリーにマップビューを追加し、コントローラーを設定します。
child: ArcGISMapView(
・・・
4. TextField のフォームで住所の入力が完了した時に実行される onSearchSubmitted メソッド(TextField の onSubmitted プロパティに設定)を作成します。onSearchSubmitted メソッドでは、LocatorTask を使用してジオコーディングを行い、その結果の座標にマーカーを表示する処理を実装しています。
void onSearchSubmitted(String value) async {
// ジオコーディング(文字列から座標を取得)用の検索パラメーターを作成します。
final geocodeParameters = GeocodeParameters()
..outputSpatialReference = _mapViewController.spatialReference;
// TextField に入力された文字列をもとにジオコーディングを実行して結果を取得します。
final geocodeResult = await _locatorTask.geocode(
searchText: value, parameters: geocodeParameters);
if (geocodeResult.isEmpty) return;
final firstResult = geocodeResult.first;
// 結果の座標にアイコンを表示して、中心になるようにマップを移動します。
final pictureMarkerSymbol = PictureMarkerSymbol.withUri(Uri.parse(
"https://static.arcgis.com/images/Symbols/Shapes/BlueStarLargeB.png"));
pictureMarkerSymbol.height = 50;
pictureMarkerSymbol.width = 50;
final graphic = Graphic(
geometry: firstResult.displayLocation, symbol: pictureMarkerSymbol);
_mapViewController.graphicsOverlays[0].graphics.add(graphic);
_mapViewController.setViewpointCenter(firstResult.displayLocation!);
}
5. 続いて、テキスト入力フォームの右横にある [X] アイコンをタップしたときに実行される dismissSearch メソッド(IconButton の onPressed プロパティに設定)を作成します。dismissSearch メソッドでは、テキスト入力フォームのテキストをクリアして、キーボードを閉じる処理を実装しています。
void dismissSearch() {
// テキスト フィールドをクリアして、キーボードを閉じます。
setState(() => _textEditingController.clear());
FocusManager.instance.primaryFocus?.unfocus();
}
6. これでジオコーディング機能を実装できたので、この状態でビルドして、機能を試してみます。住所を入力し、キーボードの完了ボタン等をタップして住所の入力を完了すると、マップ上の該当する場所にアイコンが表示されます。
リバースジオコーディング機能の実装
7. 続いて、リバースジオコーディングの機能を実装していきます。既に作成済みの ArcGISMapView ウィジェットに、マップをタップした時に呼び出される onTap プロパティを設定します。
child: ArcGISMapView(
controllerProvider: () => _mapViewController,
onMapViewReady: _onMapViewReady,
//追加
onTap: onSearchTap,
),
8. マップ上をタップした時に実行される onSearchTap メソッドを設定します。onSearchTap メソッドでは、LocatorTask を使用してリバースジオコーディングを行い、その結果の住所テキストを表示する処理を実装しています。
void onSearchTap(Offset localPosition) async {
// 既存のグラフィックスを削除します。
final graphicsOverlay = _mapViewController.graphicsOverlays[0];
if (graphicsOverlay.graphics.isNotEmpty) graphicsOverlay.graphics.clear();
// スクリーン ポイントをマップ ポイントに変換します。
final mapTapPoint =
_mapViewController.screenToLocation(screen: localPosition);
if (mapTapPoint == null) return;
// タップした場所を示すグラフィックス オブジェクトを作成します。
final pictureMarkerSymbol = PictureMarkerSymbol.withUri(Uri.parse(
"https://static.arcgis.com/images/Symbols/Shapes/BlueStarLargeB.png"));
pictureMarkerSymbol.height = 50;
pictureMarkerSymbol.width = 50;
graphicsOverlay.graphics.add(Graphic(geometry: mapTapPoint));
// リバースジオコーディング(座標から住所を取得)用の検索パラメーターを作成します。
final reverseGeocodeParameters = ReverseGeocodeParameters()..maxResults = 1;
// タップした場所とパラメーターを使用してリバースジオコーディングを実行します。
final reverseGeocodeResult = await _locatorTask.reverseGeocode(
location: mapTapPoint,
parameters: reverseGeocodeParameters,
);
if (reverseGeocodeResult.isEmpty) return;
// 結果から住所文字列を取得してダイアログに表示します。
final firstResult = reverseGeocodeResult.first;
final addressString = firstResult.label;
if (mounted) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(content: Text(addressString));
},
);
}
}
9. Nyní, když je funkce reverzního geokódování implementována, sestavím aplikaci a vyzkouším funkčnost. Když klepnete na libovolné místo na mapě, zobrazí se na mapě text s adresou tohoto místa.
Shrnutí
V tomto článku jsme použili třídu LocatorTask k implementaci funkcí geokódování a reverzního geokódování. Ačkoliv to zde nebylo možné detailně představit, třída LocatorTask nabízí několik užitečných parametrů, které lze při vyhledávání využít. Při geokódování můžete například specifikovat geografický rozsah nebo nastavit prahovou hodnotu shody mezi vyhledávaným řetězcem a skutečnou adresou pro povolení nepřesného vyhledávání.Prahová hodnota shody atd. Při reverzním geokódování lze také nastavit jazyk zobrazení adresyも設定できます。下の画像は、同じ住所を日本語と英語で表示していますが、ユーザーが選択した言語で住所の表示言語を切り替えるような機能も実装できます。
Související odkazy