Flutter地图路线绘制插件mapbox_polyline_points的使用
Flutter 地图路线绘制插件 mapbox_polyline_points 的使用
mapbox_polyline_points
是一个允许你使用 Mapbox 路径 API 在 Google 地图上绘制路径的 Flutter 插件。
开始使用
要使用此包,请在 pubspec.yaml
文件中添加 mapbox_polyline_points
作为依赖项。
dependencies:
mapbox_polyline_points: ^<最新版本号>
然后运行 flutter pub get
来安装该依赖。
导入包
在 Dart 文件中导入 mapbox_polyline_points
包:
import 'package:mapbox_polyline_points/mapbox_polyline_points.dart';
方法
通过地理坐标获取点列表,这将返回一个 MapboxPolylineResult
实例,其中包含 API 状态、错误消息和解码后的点列表。
MapboxPolylinePoints mapboxPolylinePoints = MapboxPolylinePoints();
MapboxPolylineResult result = await mapboxPolylinePoints.getRouteBetweenCoordinates(
mapboxAPiKey,
PointLatLng(latitude: _originLatitude, longitude: _originLongitude),
PointLatLng(latitude: _destLatitude, longitude: _destLongitude),
TravelType.walking // 或者 TravelType.driving
);
print(result.points);
示例
以下是一个完整的示例,展示了如何在 Flutter 应用中使用 mapbox_polyline_points
插件来绘制地图上的路线。
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:mapbox_polyline_points/mapbox_polyline_points.dart';
const LatLng _currentPosition = LatLng(28.6817149, 77.0534036);
const LatLng _currentPosition1 = LatLng(28.6277039, 77.1424405);
const LatLng _currentPosition2 = LatLng(40.698432, -73.924038);
const LatLng _currentPosition3 = LatLng(28.6730915, 77.0384241);
const LatLng _currentPosition4 = LatLng(28.6730915, 77.0384241);
class MapScreen extends StatefulWidget {
static const String routerName = "/map_screen";
const MapScreen({super.key});
[@override](/user/override)
State<MapScreen> createState() => _MapScreenState();
}
class _MapScreenState extends State<MapScreen> {
List<Marker>? _markers = [];
bool? _serviceEnabled;
late Position _locationData;
LatLng? _center;
List<List<LatLng>> polylineCoordinates = [];
GoogleMapController? mapController;
Map<PolylineId, Polyline> polylines = {};
MapboxPolylinePoints mapboxpolylinePoints = MapboxPolylinePoints();
[@override](/user/override)
void initState() {
super.initState();
_determinePosition();
}
void _determinePosition() 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.',
);
}
_locationData = await Geolocator.getCurrentPosition();
_getPolyline();
setState(() {
_center = LatLng(_locationData.latitude, _locationData.longitude);
});
}
void _addPolyLine() {
PolylineId id = PolylineId("poly");
Polyline polyline = Polyline(
polylineId: id,
width: 5,
color: Colors.greenAccent,
points: polylineCoordinates[0],
);
polylines[id] = polyline;
setState(() {});
}
void _getPolyline() async {
MapboxPolylineResult result = await mapboxpolylinePoints.getRouteBetweenCoordinates(
'pk.eyJ1IjoiYWxva2phZGhhdiIsImEiOiJjbGNnNGQxZGUwcmNiM3lrNTM3YjFnaWc4In0.4sdA4V90-ZAsGyxKxuNLiw',
PointLatLng(latitude: _locationData.latitude, longitude: _locationData.longitude),
PointLatLng(latitude: _currentPosition.latitude, longitude: _currentPosition.longitude),
TravelType.walking,
);
if (result.points.isNotEmpty) {
for (List<PointLatLng> element in result.points) {
polylineCoordinates.add(decodeEncodedPolyline(element));
}
}
_addPolyLine();
}
List<LatLng> decodeEncodedPolyline(List<PointLatLng> encoded) {
List<LatLng> poly = [];
for (int i = 0; i < encoded.length; i++) {
poly.add(LatLng(encoded[i].latitude, encoded[i].longitude));
}
return poly;
}
List<Map> listSaloon = [
{
"image": "assets/images/outlate.jpg",
"shop-name": "Afzal Cutting and sallon",
"name": "Afzal khan",
"distance": "14km"
},
{
"image": "assets/images/outlet2.jpg",
"shop-name": "Afzal Cutting and sallon",
"name": "Afzal khan",
"distance": "14km"
},
{
"image": "assets/images/outlet3.jpg",
"shop-name": "Afzal Cutting and sallon",
"name": "Afzal khan",
"distance": "14km"
},
{
"image": "assets/images/outlet4.jpg",
"shop-name": "Afzal Cutting and sallon",
"name": "Afzal khan",
"distance": "14km"
},
{
"image": "assets/images/outlet5.jpg",
"shop-name": "Afzal Cutting and sallon",
"name": "Afzal khan",
"distance": "14km"
},
];
[@override](/user/override)
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Scaffold(
body: (_center == null)
? const Center(child: CircularProgressIndicator())
: SizedBox(
width: size.width,
height: size.height,
child: Stack(
children: [
SizedBox(
width: size.width,
height: size.height,
child: GoogleMap(
initialCameraPosition: CameraPosition(
target: _center!,
zoom: 16,
),
onMapCreated: (controller) async {
mapController = controller;
var currentMarker = await BitmapDescriptor.fromAssetImage(
ImageConfiguration.empty,
"assets/images/location.png");
var markerIcon = await BitmapDescriptor.fromAssetImage(
ImageConfiguration.empty,
"assets/images/locations.png");
_markers = [
Marker(
markerId: const MarkerId("djf0"),
position: LatLng(_locationData.latitude, _locationData.longitude),
icon: currentMarker,
onTap: () {
_center = LatLng(_locationData.latitude, _locationData.longitude);
setState(() {});
},
),
Marker(
markerId: const MarkerId("djf"),
position: _currentPosition,
icon: markerIcon,
onTap: () {
_center = _currentPosition;
setState(() {});
},
),
Marker(
markerId: const MarkerId("djf1"),
position: _currentPosition1,
icon: markerIcon,
onTap: () {
_center = _currentPosition1;
setState(() {});
},
),
Marker(
markerId: const MarkerId("djf2"),
position: _currentPosition2,
icon: markerIcon,
onTap: () {
_center = _currentPosition2;
setState(() {});
},
),
Marker(
markerId: const MarkerId("djf3"),
position: _currentPosition3,
icon: markerIcon,
onTap: () {
_center = _currentPosition3;
setState(() {});
},
),
Marker(
markerId: const MarkerId("djf5"),
position: _currentPosition4,
icon: markerIcon,
onTap: () {
_center = _currentPosition4;
setState(() {});
},
),
];
setState(() {});
},
markers: _markers!.asMap().values.toSet(),
myLocationButtonEnabled: true,
polylines: Set<Polyline>.of(polylines.values),
),
),
Positioned(
bottom: 4,
left: 0,
child: SizedBox(
width: size.width,
height: size.height * 0.15,
child: ListView.builder(
itemCount: listSaloon.length,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) => InkWell(
onTap: () => _getPolyline(),
child: Container(
width: size.width * 0.35,
height: size.height * 0.15,
margin: EdgeInsets.symmetric(horizontal: 8.0),
decoration: BoxDecoration(
color: Colors.white,
boxShadow: [
BoxShadow(
offset: Offset(2.5, 2.5),
blurRadius: 5,
color: Colors.grey,
)
],
),
child: Flex(
direction: Axis.vertical,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
flex: 2,
child: Image.asset(
listSaloon[index]["image"],
fit: BoxFit.fitWidth,
),
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text(
listSaloon[index]["shop-name"],
style: TextStyle(fontSize: 10.0, fontWeight: FontWeight.w600, color: Colors.black),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
listSaloon[index]["name"],
style: TextStyle(fontSize: 8.0, fontWeight: FontWeight.w400, color: Colors.black),
),
Row(
children: [
Icon(Icons.directions_walk, size: 10),
Text(
listSaloon[index]["distance"],
style: TextStyle(fontSize: 8.0, fontWeight: FontWeight.w600, color: Colors.black),
),
],
),
],
),
],
),
),
],
),
),
),
),
),
),
Positioned(
top: 30,
left: 10,
child: ElevatedButton.icon(
style: ElevatedButton.styleFrom(
foregroundColor: Colors.black,
backgroundColor: Colors.white.withOpacity(0.2),
),
onPressed: () {
Navigator.pop(context);
},
icon: const Icon(Icons.arrow_back),
label: const Text('back'),
),
),
],
),
),
);
}
}
// 你还可以添加距离和持续时间,并且结果是一个 MapboxPolylineResult 实例
double distance = (result.distance[0].floor()) / 1000;
print(distance);
double seconds = result.distance[0];
// 将秒数转换为 Duration 对象
Duration duration = Duration(seconds: seconds.toInt());
// 提取小时、分钟和剩余的秒数
int hours = duration.inHours;
int minutes = duration.inMinutes.remainder(60);
int remainingSeconds = duration.inSeconds.remainder(60);
// 打印结果
print('$hours 小时 $minutes 分钟 $remainingSeconds 秒');
更多关于Flutter地图路线绘制插件mapbox_polyline_points的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter地图路线绘制插件mapbox_polyline_points的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter中使用mapbox_polyline_points
插件来绘制地图路线的示例代码。这个插件主要用于将GPS坐标点转换成Polyline编码格式,并可以在Mapbox或其他地图服务上绘制这些路线。
首先,确保你已经在pubspec.yaml
文件中添加了mapbox_polyline_points
和地图服务插件(例如flutter_mapbox_gl
)的依赖:
dependencies:
flutter:
sdk: flutter
mapbox_polyline_points: ^0.2.0 # 请检查最新版本号
flutter_mapbox_gl: ^0.14.0 # 请检查最新版本号,这里以Mapbox为例
然后,运行flutter pub get
来安装这些依赖。
接下来,在你的Flutter应用中,你可以按照以下步骤使用这些插件:
- 导入必要的包:
import 'package:flutter/material.dart';
import 'package:mapbox_polyline_points/mapbox_polyline_points.dart';
import 'package:flutter_mapbox_gl/flutter_mapbox_gl.dart';
- 定义你的地图和路线数据:
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MapScreen(),
);
}
}
class MapScreen extends StatefulWidget {
@override
_MapScreenState createState() => _MapScreenState();
}
class _MapScreenState extends State<MapScreen> {
final MapboxMapController _controller = MapboxMapController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Mapbox Polyline Example'),
),
body: MapboxMap(
accessToken: 'YOUR_MAPBOX_ACCESS_TOKEN', // 替换为你的Mapbox访问令牌
initialCameraPosition: CameraPosition(
target: LatLng(37.7749, -122.4194),
zoom: 13.0,
),
mapController: _controller,
onMapCreated: (controller) async {
_controller.complete(controller);
await _addPolyline(controller);
},
),
);
}
Future<void> _addPolyline(MapboxMapController controller) async {
// 定义路线坐标点
List<LatLng> points = [
LatLng(37.7749, -122.4194), // 旧金山
LatLng(34.0522, -118.2437), // 洛杉矶
];
// 使用mapbox_polyline_points将坐标点转换为Polyline字符串
PolylinePoints polylinePoints = PolylinePoints();
List<PointLatLng> result = polylinePoints.decodePolyline(
polylinePoints.encodePolyline(points),
);
// 在地图上添加PolylineLayer
controller.addPolyline(
PolylineOptions(
geometries: [
LineString(result.map((point) => LatLng(point.latitude, point.longitude)).toList()),
],
color: Colors.blue.withOpacity(0.8),
width: 5.0,
),
);
}
}
注意:
- 你需要替换
YOUR_MAPBOX_ACCESS_TOKEN
为你的实际Mapbox访问令牌。 mapbox_polyline_points
插件主要用于编码和解码Polyline,这里示例中虽然直接使用了points
列表进行编码和解码(实际上这样做是多余的,因为points
已经是一个坐标列表),但在实际应用中,你可能会从服务器获取已经编码的Polyline字符串,然后解码它以获取坐标点。flutter_mapbox_gl
插件用于在Flutter应用中显示Mapbox地图,并提供了添加PolylineLayer的方法。
这个示例展示了如何在Flutter中使用mapbox_polyline_points
和flutter_mapbox_gl
插件来绘制地图上的路线。根据你的实际需求,你可能需要调整坐标点、样式等参数。