Flutter is een blogserie waarin functies voor kaartapp-ontwikkeling worden geïntroduceerd. Dit artikel behandelt adreszoeken. We implementeren het verplaatsen van de kaart naar het ingevoerde adres en het tonen van het adres van de aangeklikte locatie op de kaart. 2 functies. In dit artikel gebruiken we deFlutter kaart SDK (ArcGIS Maps SDK for Flutter) om deze functies te implementeren.
De voorbeeldcode is GitHub gepubliceerd, dus als je snel wilt kijken, kun je deze downloaden. Hoe je de app uitvoert staat in de README vermeld. Voor het uitvoeren van het voorbeeld heb je eenAPI-sleutel nodig (gratis) .
Kaart SDK installeren en de kaart weergeven wordt uitgelegd in het blogartikel "Laten we een kaartapp maken met Flutter!". Dit artikel richt zich op de adreszoekfunctie.
Adres zoeken
Voor het gebruik van de adreszoekfunctie gebruiken we de klasse 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. Nu de reverse geocoding-functie is geïmplementeerd, ga ik de build maken en de functie testen. Wanneer je op een willekeurige plek op de kaart tikt, wordt het adres van die locatie als tekst op de kaart weergegeven.
Samenvatting
In dit artikel hebben weLocatorTask klasse gebruikt om geocoding en reverse geocoding functionaliteit te implementeren. Hoewel het hier niet volledig is behandeld, biedt deLocatorTask klasse enkele handige parameters die je kunt gebruiken bij het zoeken. Bij geocoding kun je bijvoorbeeld hetgeografische bereikspecificeren waarop gezocht wordt, of een drempel instellen voor dematchingsscore tussen de zoekterm en het daadwerkelijke adres.Bij reverse geocoding kun je ook deweergavetaal van het adresinstellen. De afbeelding hieronder toont hetzelfde adres in het Japans en Engels, maar je kunt ook functionaliteit implementeren waarbij de weergavetaal van het adres verandert op basis van de taal die de gebruiker kiest.
Gerelateerde links