Flutter地图工具插件flutter_map_toolkit的使用
Flutter地图工具插件flutter_map_toolkit的使用
本包包含了一些用于flutter_map
包的插件。
安装
首先,您必须在FlutterMap
中添加插件。
final plugins = [
PointSelectorPlugin(),
DirectionsPlugin(),
LiveMarkerPlugin(),
];
然后,在FlutterMap
小部件中设置插件属性。
FlutterMap(
plugins: plugins,
...
)
现在,您可以使用FlutterMap
的小部件层属性来使用这些插件。
FlutterMap(
plugins: plugins,
layers:[
TileLayerOptions(
...,
),
LiveMarkerOptionsWithStream(
...
),
...
]
...
)
插件
点选择器插件
点选择器插件包含两种模式:
中心点选择器
- 选择单个点在地图上
- 单击点选择器
点击点选择器
- 当用户点击地图时选择一个点
活动标记插件
活动标记插件有两种方式:
带刷新率的活动标记
- 使用
LiveMarkerOptionsWithRefreshRate
设置刷新率和标记信息提供者
带流的活动标记
- 使用
LiveMarkerOptionsWithStream
和PointInfoStreamedProvider
- 此插件将在流更新时刷新标记
- 用户与地图交互时,此插件将向提供者发送新的
MapInformationRequestParams
注意:此插件没有默认提供者,因此您必须在代码中实现PointInfoProvider
或PointInfoStreamedProvider
。
方向插件(WIP)
- 可以用来在地图上绘制路线,并可以使用
DirectionsLayerController
进行控制
注意:此插件自带MapboxDirectionProvider
- 这将使用Mapbox API为给定的航路点获取方向
DirectionsLayerOptions(
provider: mapboxProvider,
controller: directionController,
loadingBuilder: (context) {
return const Center(
child: CircularProgressIndicator(),
);
},
...
)
示例代码
以下是一个完整的示例代码,展示了如何在应用中使用flutter_map_toolkit
插件。
import 'dart:math';
import 'package:bloc/bloc.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:flutter_map_toolkit/flutter_map_toolkit.dart';
import 'package:latlong2/latlong.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter_Map_Toolkit Demo'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
[@override](/user/override)
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
DistanceInfo? distanceInfo;
static const _mapboxPublicToken =
'pk.eyJ1IjoiZm1vdGFsbGxlbGIiLCJhIjoiY2w2amFycmIwMDBkbDNsbmduNnpwczZrNyJ9.sDOg7Y2k9Nxat1MlkPj2lg';
final httpClient = Dio();
final _mapEventTap = MapTapEventHandler();
late final directionProvider = MapboxDirectionProvider(
mapboxToken: _mapboxPublicToken,
getRequestHandler: (String url) async {
final response = await httpClient.get<Map<String, dynamic>>(
url,
);
return response.data!;
},
);
final directionController = DirectionsLayerController();
final _points = <LatLng>[];
final plugins = [
PointSelectorPlugin(),
DirectionsPlugin(),
LiveMarkerPlugin(),
];
final _mapBoxAddress = mapBoxUrlBuilder(
style: 'fmotalleb/cl6m8kuee009v16pkv7m6mxgs',
is2x: true,
accessToken: _mapboxPublicToken,
);
final pointProvider = SampleStreamedPointProvider();
void onPointSelect(PointSelectionEvent event) {
if (event.state == PointSelectionState.select) {
if (event.point != null) {
// _points.add(event.point!);
setState(() {
distanceInfo = directionController.lastPath?.distanceToPoint(
event.point!,
);
});
pointProvider.controller.insert(event.point!);
}
} else if (event.point != null) {
_points.remove(event.point);
pointProvider.controller.remove(event.point!);
}
if (_points.length > 1) {
directionController.requestDirections(_points);
}
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Flexible(
child: FlutterMap(
options: MapOptions(
plugins: plugins,
minZoom: 5,
maxZoom: 18,
adaptiveBoundaries: false,
onTap: (tapPosition, point) {
_mapEventTap.update(point);
},
center: LatLng(32.553447, 53.064549),
zoom: 5,
),
layers: [
/// base map tile backed by mapbox
TileLayerOptions(
maxNativeZoom: 15,
urlTemplate: _mapBoxAddress,
),
if (distanceInfo != null) ...[
MarkerLayerOptions(
markers: [
Marker(
width: 80,
height: 80,
point: distanceInfo!.source,
builder: (ctx) => const Icon(
Icons.location_on,
color: Colors.red,
),
),
Marker(
width: 80,
height: 80,
point: distanceInfo!.destination,
builder: (ctx) => const Icon(
Icons.location_off,
color: Colors.red,
),
),
],
),
PolylineLayerOptions(
polylines: [
Polyline(
points: [
distanceInfo!.source,
distanceInfo!.destination,
],
strokeWidth: 3,
color: Colors.red,
),
],
),
],
/// direction layer for showing the route between selected points
// DirectionsLayerOptions(
// provider: directionProvider,
// useCachedRoute: true,
// controller: directionController,
// loadingBuilder: (context) {
// return const Center(
// child: CircularProgressIndicator(),
// );
// },
// ),
PointSelectorOptions(
onPointSelected: onPointSelect,
marker: MarkerInfo(
view: (context, __) => SizedBox(),
),
removeOnTap: true,
mapEventLink: _mapEventTap,
),
/// draw selected points on map
LiveMarkerOptionsWithStream(
pointsInfoProvider: pointProvider,
markers: {
'm0': MarkerInfo(
view: (_, __) => Icon(
Icons.gpp_good_sharp,
color: Colors.black.withOpacity(0.2),
)),
},
),
],
),
),
],
),
),
);
}
}
extension Randomize<T> on List<T> {
T get random => this[Random().nextInt(length)];
List<T> randomize() {
final result = toList();
result.shuffle();
return result;
}
}
class SamplePointsEventCubit extends Cubit<List<PointInfo>> {
SamplePointsEventCubit(this.iconIds, [super.initialState = const []]);
final List<String> iconIds;
final _points = <LatLng>[];
int get pointsCount => _points.length;
Iterable<PointInfo> get _information {
return _points.map(
(e) => PointInfo(
rotation: 0,
position: e,
iconId: iconIds.random,
metaData: {},
),
);
}
void refresh() {
emit(
_information.toList(),
);
}
void removeAll() {
_points.clear();
emit([]);
}
void insert(LatLng point) {
_points.add(point);
emit(_information.toList());
}
void remove(LatLng point) {
_points.remove(point);
emit(_information.toList());
}
}
class SampleStreamedPointProvider extends PointInfoStreamedProvider {
final controller = SamplePointsEventCubit([
'm0',
]);
[@override](/user/override)
Stream<List<PointInfo>> getPointStream(
Stream<MapInformationRequestParams?> params,
) =>
controller.stream;
[@override](/user/override)
void invoke() {
controller.refresh();
}
}
更多关于Flutter地图工具插件flutter_map_toolkit的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter地图工具插件flutter_map_toolkit的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何使用Flutter地图工具插件flutter_map_toolkit
的示例代码。这个插件可以帮助你更方便地在Flutter应用中使用地图功能。
首先,确保你已经在pubspec.yaml
文件中添加了flutter_map
和flutter_map_toolkit
的依赖:
dependencies:
flutter:
sdk: flutter
flutter_map: ^0.x.x # 请使用最新版本号
flutter_map_toolkit: ^0.x.x # 请使用最新版本号
然后,运行flutter pub get
来获取这些依赖。
接下来是一个简单的示例代码,展示了如何使用flutter_map_toolkit
在Flutter应用中显示一个地图,并添加一些基本的地图控件,比如缩放控件和定位控件。
import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:flutter_map_toolkit/flutter_map_toolkit.dart';
import 'package:latlong2/latlong.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Map Toolkit Example'),
),
body: FlutterMapExample(),
),
);
}
}
class FlutterMapExample extends StatefulWidget {
@override
_FlutterMapExampleState createState() => _FlutterMapExampleState();
}
class _FlutterMapExampleState extends State<FlutterMapExample> {
final MapController _controller = MapController();
@override
Widget build(BuildContext context) {
return FlutterMap(
mapController: _controller,
options: MapOptions(
center: LatLng(45.5236, -122.6750), // 地图中心点
zoom: 13.0,
),
layers: [
TileLayerOptions(
urlTemplate: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
subdomains: ['a', 'b', 'c'],
),
// 添加定位控件
MapToolkitLayer(
options: MapToolkitOptions(
myLocationEnabled: true,
myLocationButtonBuilder: (context) {
return IconButton(
icon: Icon(Icons.location_on),
onPressed: () {
// 处理定位按钮点击事件
// 这里可以调用_controller.moveTo来移动到当前位置
},
);
},
),
),
// 添加缩放控件
MapToolkitLayer(
options: MapToolkitOptions(
zoomControlEnabled: true,
),
),
],
);
}
}
在这个示例中,我们创建了一个Flutter应用,并在主页上展示了一个地图。我们使用了flutter_map
和flutter_map_toolkit
来配置和显示地图。以下是几个关键点:
- MapController:用于控制地图的状态,比如缩放和移动。
- MapOptions:配置地图的中心点、缩放级别等。
- TileLayerOptions:配置地图的图层,这里使用的是OpenStreetMap的图层。
- MapToolkitLayer:
flutter_map_toolkit
提供的图层,用于添加各种地图控件,比如定位控件和缩放控件。
注意:
- 你可能需要根据实际情况调整
urlTemplate
和其他配置。 - 定位功能可能需要额外的权限和设置,特别是在移动设备上。
- 确保你使用的
flutter_map
和flutter_map_toolkit
版本兼容。
希望这个示例代码能帮助你开始使用flutter_map_toolkit
!