Flutter Map路线绘制报错:API响应无路线数据求助
Flutter Map 路线加载异常:No route data available in the API response
问题描述
使用Flutter框架开发,集成flutter_map、polylines、markers组件和OpenRouteService路线服务,运行代码后始终抛出异常:Error: Exception: No route data available in the API response。手动测试API密钥可正常获取路线数据,需排查问题原因。
代码示例
import 'package:flutter/material.dart'; import 'package:flutter_map/flutter_map.dart'; import 'package:latlong2/latlong.dart'; import 'package:http/http.dart' as http; import 'dart:convert'; void main() { runApp(const MyApp()); } class MyApp extends StatefulWidget { const MyApp({super.key}); @override _MyAppState createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { Future<List<LatLng>>? route; @override void initState() { super.initState(); route = fetchRoute( LatLng(28.58256157514347, 77.32420983539001), LatLng(28.518005096303668, 77.38189447010934), ); } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: const Text('Flutter Map Example')), body: FutureBuilder<List<LatLng>>( future: route, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return Center(child: CircularProgressIndicator()); } else if (snapshot.hasError) { return Center(child: Text('Error: ${snapshot.error}')); } else if (!snapshot.hasData || snapshot.data == null || snapshot.data!.isEmpty) { return Center(child: Text('No route data available')); } else { return FlutterMap( options: MapOptions( initialCenter: LatLng(28.550283, 77.348052), initialZoom: 12.0, ), children: [ TileLayer( urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png', userAgentPackageName: 'com.example.app', maxZoom: 19.0, ), MarkerLayer( markers: [ Marker( point: LatLng(28.58256157514347, 77.32420983539001), width: 80, height: 80, child: Container( child: Icon( Icons.pin_drop, color: Colors.red, size: 40, ), ), ), Marker( point: LatLng(28.518005096303668, 77.38189447010934), width: 80, height: 80, child: Container( child: Icon( Icons.pin_drop, color: Colors.red, size: 40, ), ), ), ], ), PolylineLayer( polylines: [ Polyline( points: snapshot.data!, color: Colors.blue, strokeWidth: 4.0, ), ], ), ], ); } }, ), ), ); } Future<List<LatLng>> fetchRoute(LatLng start, LatLng end) async { final apiKey = 'API KEY'; // Replace with your API key final url = 'https://api.openrouteservice.org/v2/directions/driving-car?api_key=$apiKey&start=${start.longitude},${start.latitude}&end=${end.longitude},${end.latitude}'; final response = await http.get(Uri.parse(url)); if (response.statusCode == 200) { final data = jsonDecode(response.body); print('API Response: $data'); if (data['routes'] != null && data['routes'].isNotEmpty) { final route = data['routes'][0]['geometry']['coordinates'] as List; print('Route Coordinates: $route'); return route.map((point) => LatLng(point[1], point[0])).toList(); } else { throw Exception('No route data available in the API response'); } } else { throw Exception('Failed to load route. Status code: ${response.statusCode}'); } } }
排查与解决建议
检查API响应的错误信息
OpenRouteService即使返回200状态码,也可能在响应体中包含error字段(比如密钥权限不足、请求配额耗尽)。在解析前添加错误检查,能明确问题原因:if (data.containsKey('error')) { throw Exception('API错误: ${data['error']['message']}'); }验证JSON解析路径
确认API返回的routes[0].geometry.coordinates结构是否符合预期。打印完整响应后,检查是否存在嵌套层级错误,可通过请求参数format=geojson确保返回标准GeoJSON结构。添加层级存在性校验
原代码直接访问data['routes'][0]['geometry']['coordinates'],若某一层级不存在会导致解析失败。增加逐层校验,避免空指针或结构不匹配:if (routeData['geometry'] != null && routeData['geometry']['coordinates'] != null) { final coordinates = routeData['geometry']['coordinates'] as List; return coordinates.map((point) => LatLng(point[1], point[0])).toList(); } else { throw Exception('响应中缺少路线几何数据'); }确认网络权限配置
检查Flutter项目的网络权限:- Android:在
android/app/src/main/AndroidManifest.xml中添加<uses-permission android:name="android.permission.INTERNET"/> - iOS:确保
Info.plist中未限制HTTPS请求(默认允许,无需额外配置)
- Android:在
修改后的fetchRoute函数示例
Future<List<LatLng>> fetchRoute(LatLng start, LatLng end) async { final apiKey = '你的API密钥'; final url = 'https://api.openrouteservice.org/v2/directions/driving-car?api_key=$apiKey&start=${start.longitude},${start.latitude}&end=${end.longitude},${end.latitude}'; final response = await http.get(Uri.parse(url)); if (response.statusCode == 200) { final data = jsonDecode(response.body); // 优先检查API返回的错误信息 if (data.containsKey('error')) { throw Exception('API错误: ${data['error']['message']}'); } print('完整API响应: $data'); if (data['routes'] != null && data['routes'].isNotEmpty) { final routeData = data['routes'][0]; // 校验几何数据是否存在 if (routeData['geometry'] != null && routeData['geometry']['coordinates'] != null) { final coordinates = routeData['geometry']['coordinates'] as List; return coordinates.map((point) => LatLng(point[1], point[0])).toList(); } else { throw Exception('响应中缺少路线几何数据'); } } else { throw Exception('API响应中无可用路线数据'); } } else { throw Exception('加载路线失败,状态码: ${response.statusCode}'); } }
内容的提问来源于stack exchange,提问作者Asim Reyazuddin
相关产品推荐
相关产品推荐

