Flutter地图导航插件navigation_map的使用

发布于 1周前 作者 yuanlaile 来自 Flutter

Flutter地图导航插件navigation_map的使用

NavigationMap 是一个用于在交互式地图上进行实时导航、位置跟踪和路线可视化的 Flutter 插件。它基于 flutter_map 构建,并支持固定标记、当前速度和路线绘制等功能。

特性

  • 显示当前位置并跟踪移动。
  • 绘制位置之间的路线。
  • 添加固定位置标记。
  • 获取实时速度(单位:公里/小时)。
  • 使用反向地理编码获取位置名称。

安装

在你的 pubspec.yaml 文件中添加 navigation_map

dependencies:
  navigation_map: ^0.0.1
  latlong2: 0.9.1

根据目标平台配置相应的权限。

对于 Android

  1. 在你的 gradle.properties 文件中添加以下内容:

    android.useAndroidX=true
    android.enableJetifier=true
    
  2. 确保你在 android/app/build.gradle 文件中将 compileSdkVersion 设置为 34:

    android {
      compileSdkVersion 34
    
      ...
    }
    
  3. AndroidManifest.xml 中设置权限:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android">
    
        <uses-permission android:name="android.permission.INTERNET" />
        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
        <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />    
        <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
    
        <application
    
  4. 如果出现 Kotlin 版本错误,更新到最新版本的 Kotlin:

    plugins {
        id "dev.flutter.flutter-plugin-loader" version "1.0.0"
        id "com.android.application" version "7.3.0" apply false
        id "org.jetbrains.kotlin.android" version "2.0.21" apply false
    }
    

对于 iOS

  1. 在你的 Info.plist 文件中添加以下内容(位于 ios/Runner 目录下):

    <key>NSLocationWhenInUseUsageDescription</key>
    <string>This app needs access to location when open.</string>
    

有关 Android 和 iOS 的更多配置信息,请访问 geolocator 包在 Pub.dev 上的页面。

使用文档

  1. 加载地图并获取当前位置

    Widget build(BuildContext context) {
      final GlobalKey<NavigationMapState> navMapKey = GlobalKey();
    
      return SafeArea(
        child: Scaffold(
          body: NavigationMap(
            key: navMapKey,
          ),
        ),
      );
    }
    
  2. 获取当前位置的经纬度坐标

    final location = navMapKey.currentState?.getCurrentLocation();
    if (location != null) {
      print(location);
    }
    
  3. 添加固定位置

    final mapState = navMapKey.currentState;
    if (mapState != null) {
      // 示例固定位置
      mapState.addFixedLocation(
        LatLng(6.927079, 79.861244)); // 替换为你自己的 LatLng
    }
    
  4. 定义一条路线

    navMapKey.currentState?.clearRoute(); 
    navMapKey.currentState?.fetchRoute(
      LatLng(37.7749, -122.4194), 
      LatLng(34.0522, -118.2437)
    );
    
  5. 获取距离(单位:米)

    final mapState = navMapKey.currentState;
    if (mapState != null) {
      LatLng colombo = LatLng(6.9271, 79.8612);
      LatLng galle = LatLng(6.0328, 80.2168);
      double distance = mapState.calculateDistance(colombo, galle);
    
      print("Distance: $distance meters");
    }
    
  6. 清除已设置的路线

    navMapKey.currentState?.clearRoute(); 
    
  7. 获取当前速度(单位:公里/小时)

    print(navMapKey.currentState?.getCurrentSpeed());
    
  8. 获取位置名称

    floatingActionButton: FloatingActionButton(
      onPressed: () async {
        final mapState = navMapKey.currentState;
        LatLng colombo = LatLng(6.9271, 79.8612);
        if (mapState != null) {
          String? locationName = await mapState.getLocationName(colombo);
          if (locationName != null) {
            print("Location Name: $locationName");
          } else {
            print("Could not retrieve location name.");
          }
        }
      },
    )
    

示例代码

以下是完整的示例代码,你可以将其复制到你的项目中以测试 navigation_map 插件的功能。

import 'package:flutter/material.dart';
import 'package:navigation_map/navigation_map.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: const Home(),
    );
  }
}

class Home extends StatefulWidget {
  const Home({super.key});

  [@override](/user/override)
  State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home> {
  final GlobalKey<NavigationMapState> navMapKey = GlobalKey();

  [@override](/user/override)
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        body: NavigationMap(
          key: navMapKey,
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            final mapState = navMapKey.currentState;
            LatLng colombo = LatLng(6.9271, 79.8612);
            if (mapState != null) {
              String? locationName = mapState.getLocationName(colombo);
              if (locationName != null) {
                print("Location Name: $locationName");
              } else {
                print("Could not retrieve location name.");
              }
            }
          },
        ),
      ),
    );
  }
}

更多关于Flutter地图导航插件navigation_map的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter地图导航插件navigation_map的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter应用中使用navigation_map插件来实现地图导航的一个示例代码案例。navigation_map插件结合了地图显示和导航功能,通常基于Google Maps或其他地图服务。请注意,实际使用中你可能需要替换或添加API密钥等配置。

首先,确保在pubspec.yaml文件中添加依赖:

dependencies:
  flutter:
    sdk: flutter
  navigation_map: ^最新版本号  # 请替换为实际最新版本号

然后运行flutter pub get来安装依赖。

接下来,创建一个Flutter页面,用于显示地图并实现导航功能。以下是一个简单的示例代码:

import 'package:flutter/material.dart';
import 'package:navigation_map/navigation_map.dart';
import 'package:geolocator/geolocator.dart';
import 'package:geocoding/geocoding.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: NavigationMapScreen(),
    );
  }
}

class NavigationMapScreen extends StatefulWidget {
  @override
  _NavigationMapScreenState createState() => _NavigationMapScreenState();
}

class _NavigationMapScreenState extends State<NavigationMapScreen> {
  late GoogleMapController _controller;
  late LatLng _currentPosition;
  late LatLng _destinationPosition;

  @override
  void initState() {
    super.initState();
    _getCurrentLocation();
    _getDestinationLocation();
  }

  Future<void> _getCurrentLocation() async {
    bool serviceEnabled;
    LocationPermission permission;

    serviceEnabled = await Geolocator.isLocationServiceEnabled();
    if (!serviceEnabled) {
      return Future.error('Location services are disabled.');
    }

    permission = await Geolocator.checkPermission();
    if (permission == LocationPermission.denied) {
      permission = await Geolocator.requestPermission();
      if (permission == LocationPermission.denied) {
        return Future.error('Location permissions are denied');
      }
    }

    if (permission == LocationPermission.deniedForever) {
      return Future.error(
          'Location permissions are permanently denied, we cannot request permissions.');
    }

    Position position = await Geolocator.getCurrentPosition(
        desiredAccuracy: LocationAccuracy.high);
    setState(() {
      _currentPosition = LatLng(position.latitude!, position.longitude!);
    });
  }

  Future<void> _getDestinationLocation() async {
    List<Placemark> placemarks = await placemarkFromCoordinates(
        LatLng(37.7749, -122.4194)); // 示例坐标:旧金山

    setState(() {
      _destinationPosition = LatLng(37.7749, -122.4194);
    });
  }

  void _startNavigation() {
    // 这里你需要实现具体的导航逻辑,
    // 可能需要调用第三方导航服务的API(如Google Maps Directions API)
    // 然后根据返回的路径数据在地图上绘制路线
    // 这是一个简化的示例,实际中需要更多代码来实现完整功能
    print('Starting navigation from $_currentPosition to $_destinationPosition');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Navigation Map'),
      ),
      body: GoogleMap(
        mapType: MapType.normal,
        initialCameraPosition: CameraPosition(
          target: _currentPosition,
          zoom: 14,
        ),
        onMapCreated: (GoogleMapController controller) {
          _controller = controller;
          // 可以在这里添加标记、多边形等
          _controller.addMarker(
            MarkerOptions(
              position: _currentPosition,
              infoWindowText: InfoWindowText('Current Location', ''),
            ),
          );
          _controller.addMarker(
            MarkerOptions(
              position: _destinationPosition,
              infoWindowText: InfoWindowText('Destination', ''),
              icon: BitmapDescriptor.defaultMarkerWithHue(
                BitmapDescriptor.hueAzure,
              ),
            ),
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _startNavigation,
        tooltip: 'Start Navigation',
        child: Icon(Icons.directions),
      ),
    );
  }
}

注意事项:

  1. 权限处理:上述代码处理了位置权限的请求,但在实际应用中,你需要在AndroidManifest.xmlInfo.plist中添加必要的权限声明。

  2. API密钥:对于Google Maps服务,你需要在Google Cloud Platform上创建一个项目并启用相应的API,然后获取API密钥并在代码中配置。

  3. 导航实现:上述代码中的_startNavigation方法仅打印了导航开始的消息。在实际应用中,你需要调用导航服务的API(如Google Maps Directions API)来获取导航路径,并在地图上绘制该路径。

  4. 依赖管理:确保所有依赖项(如geolocatorgeocoding)都已正确安装并配置。

  5. 错误处理:在生产代码中,应添加更多的错误处理逻辑,以处理位置服务不可用、权限被拒绝等情况。

希望这个示例能帮助你开始在Flutter应用中使用navigation_map插件。如果你使用的是其他具体的导航插件或有特定需求,请查阅该插件的官方文档以获取更详细的信息。

回到顶部