Este es un artículo de blog que presenta en serie las funciones que se pueden usar para desarrollar aplicaciones de mapas con Flutter.En las aplicaciones móviles de mapas, la función para mostrar el mapa sincronizado con la ubicación actual del dispositivo es una función comúnmente mencionada. En este artículo, presentamos cómo implementar esta función usando el SDK de mapas para Flutter (ArcGIS Maps SDK for Flutter).
El código de ejemplo está disponible en GitHub, así que si quieres revisarlo inmediatamente, descárgalo. Las instrucciones para ejecutar la aplicación están en README. Para ejecutar el ejemplo, necesitas obtener una clave API (gratuita).
Para la introducción del SDK de mapas y cómo mostrar el mapa, consulta el artículo del blog "Flutter で地図アプリを作成してみよう!". En este artículo nos enfocamos en la función para mostrar el mapa sincronizado con la ubicación actual.
Agregar permisos
Para que la aplicación acceda a la información de ubicación del dispositivo, es necesario agregar los siguientes permisos. Añade cada permiso en el archivo correspondiente.
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>NSLocatS_FINE_LOCATION" />ionUsageDescription</key>
<string>Se requiere permiso para usar la ubicación en la aplicación para acceder a la información de ubicación.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Se requiere permiso para usar la ubicación en la aplicación para acceder a la información de ubicación.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Se requiere permiso para usar la ubicación en la aplicación para acceder a la información de ubicación.</string>
La cadena configurada en la etiqueta string del Info.plist es el mensaje que se muestra al usuario cuando se solicita acceso a la ubicación. Configura un mensaje personalizado.
Implementación de la función para mostrar la ubicación actual
Para mostrar la ubicación actual en el mapa se usa la clase LocationDisplay. LocationDisplay obtiene la ubicación actual desde la fuente de datos especificada por LocationDataSource, y muestra un símbolo de ubicación en el mapa. Cuando la ubicación actual se actualiza, también se actualiza automáticamente la posición del símbolo en el mapa. Además, cuando se actualizan la ubicación, orientación y dirección, el mapa puede moverse o rotar automáticamente.
1. En el paso 6 del artículo del blog "Flutter で地図アプリを作成してみよう!", después de configurar el mapa creado en el controlador del MapView y mostrarlo, configura en LocationDisplay del _mapViewController la fuente de datos que será origen de la información de ubicación.
…
// Configura el mapa creado en el controlador del MapView.
_mapViewController.arcGISMap = map;
// Adición
// Configura para mostrar en el mapa la ubicación actual desde el servicio de localización del sistema.
_mapViewController.locationDisplay.dataSource = SystemLocationDataSource();
Puedes configurar como fuente de datos SystemLocationDataSource o 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)),
);
}
}
非同期に関するエラーが発生したら、_onMapViewReady 関数に async を付けて、下記のように変更します。
Future<void> _onMapViewReady() async {
これで、デバイスが現在地を取得できる場合に、現在地を示す青いシンボルがマップの中心に表示されるはずです。
4. 続いて、位置情報の取得の開始/停止と AutoPanMode を切り替える UI を実装します。まず、これらの UI を含む locationSettings ウィジェットを作成します。
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(
'表示設定',
style: Theme.of(context).textTheme.titleLarge,
),
const Spacer(),
],
),
Row(
children: [
const Text('ロケーションの表示'),
const Spacer(),
// 位置情報の取得を開始および停止するためのスイッチです。
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('Recentrar'), // Acerca el mapa para que la ubicación actual quede en el centro
),
DropdownMenuItem(
value: LocationDisplayAutoPanMode.navigation,
child: Text(
'Navigation'), // Muestra siempre la ubicación actual en la parte inferior del mapa y rota el mapa según la dirección del dispositivo
),
DropdownMenuItem(
value: LocationDisplayAutoPanMode.compassNavigation,
child: Text(
'Compass'), // Muestra siempre la ubicación actual en el centro del mapa y rota el mapa según la orientación del dispositivo
),
],
),
],
),
],
),
);
}
5. Añade el widget locationSettings creado en el paso anterior dentro del Expanded que contiene ArcGISMapView.
children: [
Expanded(
// Añade el MapView al árbol de widgets y configura el controlador.
child: ArcGISMapView(
controllerProvider: () => _mapViewController,
onMapViewReady: _onMapViewReady,
),
),
// Añade el widget locationSettings debajo de la pantalla del mapa.
locationSettings(context),
],
6. Al inicio de la clase _MyHomePageState, crea la variable _isLocationStarted para controlar el estado de LocationDisplay. En el widget locationSettings, cuando LocationDisplay se inicia (start), activa el interruptor "Mostrar ubicación"; cuando LocationDisplay se detiene (stop), desactívalo.
bool _isLocationStarted = true;
7. Finalmente, abre lib/main.dart y después de las líneas de importación ya existentes, añade el siguiente código para importar los paquetes necesarios para el proceso.
import 'dart:math';
Con esto, la interfaz para iniciar/detener la obtención de ubicación y cambiar AutoPanMode está completa. Ejecuta la aplicación y prueba cambiar AutoPanMode para verificar cómo funciona cada modo.
Resumen
En este artículo implementamos una función para mostrar un mapa sincronizado con la ubicación actual del dispositivo. La clase LocationDisplay permite configurar opciones no mencionadas aquí, como cambiar el símbolo de ubicación, la escala del mapa al mostrar inicialmente la ubicación o la posición de visualización en modo Navigation. Te animamos a personalizarlo a tu estilo y probarlo.
Enlaces relacionados