You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用google_maps_flutter Flutter包展示已保存的编码地图路线及导航指引?

实现已保存路线展示+自定义导航指引的方案

首先得明确:目前没有现成的Flutter包能直接加载你保存的路线编码,同时提供像谷歌地图APP那样的原生导航指引。但我们可以通过两种思路来实现你的需求,下面详细说明:


方案1:解析路线编码,自行实现导航指引逻辑

这种方式适合你只保存了Polyline编码字符串的情况,核心是自己处理位置匹配和指引生成:

步骤1:解码路线并绘制Polyline

先用polyline解码包(比如polyline_encoder)把你保存的编码字符串转成坐标列表,再用google_maps_flutter画出路线:

import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:polyline_encoder/polyline_encoder.dart';

List<LatLng> decodeSavedRoute(String encodedPolyline) {
  final decodedPoints = PolylineDecoder.decodePolyline(encodedPolyline);
  return decodedPoints.map((p) => LatLng(p.latitude, p.longitude)).toList();
}

// 在GoogleMap的polylines中使用
Set<Polyline> _polyline = {
  Polyline(
    polylineId: const PolylineId("saved_route"),
    points: decodeSavedRoute(yourEncodedString),
    color: Colors.blue,
    width: 5,
  )
};

步骤2:实时匹配位置并生成指引

使用geolocator获取用户实时位置,结合地理计算包(比如latlong2)来判断用户在路线上的位置,进而生成导航提示:

  • 先把解码后的路线坐标拆分成路段(比如每两个连续坐标点为一段)
  • 计算用户当前位置到各路段的距离,找到最近的路段
  • 定位到下一个转弯点(如果你的路线编码包含转弯点信息,或者你保存路线时额外记录了转弯坐标),计算距离和方向,生成类似“前行300米左转”的提示

示例代码片段:

import 'package:geolocator/geolocator.dart';
import 'package:latlong2/latlong.dart';

// 监听位置变化
void startLocationTracking(List<LatLng> routePoints) {
  Geolocator.getPositionStream(
    locationSettings: const LocationSettings(accuracy: LocationAccuracy.high),
  ).listen((position) {
    final currentLatLng = LatLng(position.latitude, position.longitude);
    final distanceCalculator = Distance();

    // 找到离用户最近的路线点
    LatLng nearestPoint = routePoints.first;
    double minDistance = double.infinity;
    for (var point in routePoints) {
      final distance = distanceCalculator.as(
        LengthUnit.Meter,
        LatLng(currentLatLng.latitude, currentLatLng.longitude),
        LatLng(point.latitude, point.longitude),
      );
      if (distance < minDistance) {
        minDistance = distance;
        nearestPoint = point;
      }
    }

    // 假设下一个转弯点是routePoints中的第N个点,这里需要你根据保存的路线逻辑判断
    final nextTurnPoint = routePoints[routePoints.indexOf(nearestPoint) + 5];
    final distanceToTurn = distanceCalculator.as(
      LengthUnit.Meter,
      currentLatLng,
      nextTurnPoint,
    );

    // 生成指引文本(这里的转弯方向需要根据路线走向判断,你可以通过计算方位角实现)
    setState(() {
      currentNavigationHint = "前行${distanceToTurn.round()}米后左转";
    });
  });
}

方案2:保存完整路线步骤,配合位置展示指引

如果你最初是通过Google Maps Directions API生成的路线,建议不仅保存Polyline编码,还要保存完整的路线steps数据(包含每个路段的指引文本、距离、起止坐标等)。这样后续可以直接复用这些steps来展示导航提示:

步骤1:保存路线时记录Steps

调用Directions API后,把DirectionsResponse中的legs[0].steps序列化(比如转成JSON)存入数据库:

// 假设你通过google_maps_webservice获取路线
import 'package:google_maps_webservice/directions.dart';

final directions = GoogleMapsDirections(apiKey: "YOUR_API_KEY");
final response = await directions.directions(
  Location(originLat, originLng),
  Location(destLat, destLng),
);

// 保存steps到数据库
final savedStepsJson = jsonEncode(response.routes.first.legs.first.steps);
// 存入数据库...

步骤2:加载Steps并匹配位置展示指引

从数据库取出steps数据,反序列化为对象,然后监听用户位置,判断当前处于哪个step,直接展示对应的指引文本:

// 从数据库取出并反序列化steps
List<Step> savedSteps = (jsonDecode(savedStepsJson) as List)
    .map((e) => Step.fromJson(e))
    .toList();

// 监听位置,匹配当前step
Geolocator.getPositionStream().listen((position) {
  final currentLoc = LatLng(position.latitude, position.longitude);
  final distanceCalculator = Distance();

  // 找到当前用户所在的step
  Step currentStep = savedSteps.firstWhere((step) {
    final startDistance = distanceCalculator.as(
      LengthUnit.Meter,
      currentLoc,
      LatLng(step.startLocation.lat, step.startLocation.lng),
    );
    final endDistance = distanceCalculator.as(
      LengthUnit.Meter,
      currentLoc,
      LatLng(step.endLocation.lat, step.endLocation.lng),
    );
    // 判断用户是否在当前step的路段范围内
    return startDistance < 100 && endDistance < 300;
  });

  // 直接展示API返回的指引文本
  setState(() {
    currentNavigationHint = currentStep.instructions;
  });
});

局限性说明

  • 自行实现的导航指引无法完全媲美谷歌地图APP的原生体验,比如处理路线偏离后的重新规划、复杂路口的可视化指引等,都需要额外开发逻辑。
  • 如果你想用谷歌地图APP的原生导航功能,目前无法加载自定义的已保存路线——因为谷歌地图APP的导航是基于实时路况计算的最优路线,不支持导入外部路线数据。

内容的提问来源于stack exchange,提问作者Ajantha Bandara

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.01 00:02:43