Dit is een blogserie waarin functies voor het ontwikkelen van kaartapps met Flutter worden geïntroduceerd.In mobiele kaartapps is het vaak voorkomend om de kaart te tonen gekoppeld aan de huidige locatie van het apparaat. In dit artikel wordt uitgelegd hoe je die functie implementeert met de Flutter-kaart SDK (ArcGIS Maps SDK for Flutter).
De voorbeeldcode is beschikbaar op GitHub, dus als je snel wilt controleren, kun je deze downloaden. Hoe je de app uitvoert staat beschreven in README. Om het voorbeeld uit te voeren heb je een API sleutel nodig (gratis).
Voor het installeren van de kaart SDK en het weergeven van de kaart, zie het blogartikel "Flutter kaartapp maken!". Dit artikel richt zich op het tonen van de kaart gekoppeld aan de huidige locatie.
Permissies toevoegen
Om toegang te krijgen tot de locatiegegevens van het apparaat in je app, moet je de volgende permissies toevoegen. Voeg deze toe aan de betreffende bestanden.
Android
android/app/src/main/AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
iOS
ios/Runner/Info.plist
<key>NSLocationUsageDescription</key>
<string>Toegang tot locatiegegevens vereist toestemming voor gebruik van locatie in de app.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Toegang tot locatiegegevens vereist toestemming voor gebruik van locatie in de app.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Toegang tot locatiegegevens vereist toestemming voor gebruik van locatie in de app.</string>
De tekst die je instelt in de string-tag van Info.plist wordt getoond aan gebruikers wanneer ze gevraagd worden om toegang tot hun locatie. Stel hier een passende boodschap in.
Implementatie van functie voor huidige locatie weergeven
De functie om de huidige locatie op de kaart te tonen maakt gebruik van de klasse LocationDisplay. LocationDisplay haalt de huidige locatie op uit de datasources die zijn opgegeven via LocationDataSource で指定したデータソースから現在地を取得し、マップ上に現在地のシンボルを表示します。現在地が更新されると、マップ上のシンボルの位置も自動で更新されます。また、現在地、方位、進行方向が更新されたときにマップを自動的に移動や回転させることもできます。
1. 「Flutter で地図アプリを作成してみよう!」のブログ記事の手順 6 で、マップビュー コントローラーに作成したマップを設定してマップの表示までできたら、_mapViewController の LocationDisplay に位置情報のソースとなるデータ ソースを設定します。
・・・
// マップビュー コントローラーに作成したマップを設定します。
_mapViewController.arcGISMap = map;
// 追加
// システムの位置情報サービスの現在位置をマップ上に表示するように設定します。
_mapViewController.locationDisplay.dataSource = SystemLocationDataSource();
データ ソースには、SystemLocationDataSource と SimulatedLocationDataSource を設定できます。SystemLocationDataSource はデバイス システムで使用される位置情報を使用します。SimulatedLocationDataSource はテスト用にシミュレートされたデバイスの位置情報を使用できます。現在地 (ArcGISLocation) のコレクションを使用するか、setLocationsWithPolyline メソッドで移動速度とラインを指定して、ラインに沿って現在地を移動させることもできます。
2. 続いて、位置情報が更新されたときにマップをどのように表示/移動させるかを AutoPanMode を使用して設定します。
// AutoPanMode を Recenter モードに設定します。
_mapViewController.locationDisplay.autoPanMode = LocationDisplayAutoPanMode.recenter;
AutoPanMode は、徒歩や車両でのナビゲーション用に以下の表示モードが用意されています。アプリの用途に応じて適切なモードを選択/切替えて利用できます。
- Recenter: 現在地が wanderExtentFactor で設定された範囲外に移動したときに、現在地を再度画面の中心に表示するようにマップが自動で移動します。wanderExtentFactor には、0 から 1 の間の値を設定します。0 の場合は、現在地が更新される度にマップが移動します。1 の場合は、現在地が現在のマップの表示範囲の端に達したときにマップが移動します。
- Navigation: 現在地が常に画面の下部に表示されるようにマップが自動で移動します。また、進行方向が常にデバイス上端を向くように、進行方向に基づいて自動でマップが回転します。車両での移動を想定したモードです。
- Compass Navigation: 現在地が常に画面の中心に表示されるようにマップが自動で移動します。また、向いている方向が常にデバイス上端を向くように、向きに基づいて自動でマップが回転します。徒歩での移動を想定したモードです。
- Off: 現在地のみが更新され、地図は自動で移動しません。
3. 位置情報の取得を開始するための準備ができたので LocationDisplay の start メソッドを呼び出します。
// 位置情報の取得を開始します(これにより、ユーザーに許可を求めるプロンプトが表示されます)。
try {
await _mapViewController.locationDisplay.dataSource.start();
} on ArcGISException catch (e) {
if (mounted) {
showDialog(
context: context,
builder: (_) => AlertDialog(content: Text(e.message)),
);
}
}
Als er fouten optreden bij asynchrone bewerkingen, voeg dan async toe aan functie _onMapViewReady en wijzig deze zoals hieronder.
Future<void> _onMapViewReady() async {
Als alles goed gaat, zal er een blauw symbool voor huidige locatie centraal op de kaart verschijnen zodra het apparaat zijn positie kan bepalen.
4. Implementeer vervolgens UI om starten/stoppen van locatiedata ophalen en wisselen tussen AutoPanModes mogelijk te maken. Maak eerst widget locationSettings die deze UI bevat.
Widget locationSettings(BuildContext context) {
return Container(
padding: EdgeInsets.fromLTRB(
20.0,
20.0,
20.0,
max(
20.0,
View.of(context).viewPadding.bottom / View.of(context).devicePixelRatio,
),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
children: [
Text(
'Weergave-instellingen',
style: Theme.of(context).textTheme.titleLarge,
),
'const Spacer()',
),
),
'Row('
'children:['
'const Text('Locatie weergeven')',
'const Spacer()',
// Schakelaar om starten/stoppen ophalen locatiedata te regelen.
'Switch('
'value: _isLocationStarted,'
'onChanged: (value) {',
'setState(() {',
'if (_mapViewController.locationDisplay.dataSource.status == LocationDataSourceStatus.started) {',
' _mapViewController.locationDisplay.stop();',
' _isLocationStarted = false;',
} else {
_mapViewController.locationDisplay.start();
_isLocationStarted = true;
}
} );
},
),
],
),
Row(
children: [
const Text('Auto-Pan モード'),
const Spacer(),
// AutoPanMode を選択するためのドロップダウン ボタンです。
DropdownButton(
value: _mapViewController.locationDisplay.autoPanMode,
onChanged: (value) {
setState(() {
_mapViewController.locationDisplay.autoPanMode = value!;
});
},
items: const [
DropdownMenuItem(
value: LocationDisplayAutoPanMode.off,
child: Text('Off'), // 現在位置のシンボルをマップ上に表示するのみ
),
DropdownMenuItem(
value: LocationDisplayAutoPanMode.recenter,
child: Text('Opnieuw centreren'), // Zoom de kaart zodat de huidige locatie in het midden staat
),
DropdownMenuItem(
value: LocationDisplayAutoPanMode.navigation,
child: Text(
'Navigatie'), // Toon de huidige locatie altijd onderaan de kaart en roteer de kaart op basis van de rijrichting van het apparaat
),
DropdownMenuItem(
value: LocationDisplayAutoPanMode.compassNavigation,
child: Text(
'Kompas'), // Toon de huidige locatie altijd in het midden van de kaart en roteer de kaart op basis van de richting waarin het apparaat wijst
),
],
),
],
),
],
),
);
}
5. Voeg in Expanded met ArcGISMapView het eerder gemaakte locationSettings-widget toe.
children: [
Expanded(
// Voeg de mapview toe aan de widgetboom en stel de controller in.
child: ArcGISMapView(
controllerProvider: () => _mapViewController,
onMapViewReady: _onMapViewReady,
),
),
// Voeg onder het kaartscherm het locationSettings-widget toe.
locationSettings(context),
],
6. Maak aan het begin van de _MyHomePageState-klasse een variabele _isLocationStarted om de status van LocationDisplay bij te houden. In het locationSettings-widget wordt de "Locatie weergeven"-schakelaar aangezet wanneer LocationDisplay is gestart (start) en uitgezet wanneer LocationDisplay is gestopt (stop).
bool _isLocationStarted = true;
7. Open tenslotte lib/main.dart en voeg na de reeds geschreven importregels onderstaande code toe om de benodigde pakketten te importeren.
import 'dart:math';
Hiermee is de UI voor het starten/stoppen van locatiebepaling en het wisselen van AutoPanMode voltooid. Start de app en wissel tussen AutoPanModes om het gedrag van elke modus te bekijken.
Samenvatting
In dit artikel hebben we een functie geïmplementeerd die een kaart toont gekoppeld aan de huidige locatie van het apparaat. Met de LocationDisplay-klasse kun je ook instellingen aanpassen die hier niet besproken zijn, zoals het wijzigen van het locatiesymbool, de schaal waarop wordt ingezoomd bij eerste weergave, en waar de locatie wordt weergegeven in Navigatiemodus. Pas deze gerust aan naar je eigen stijl en probeer ze uit.
Gerelateerde links