一、什么是FlutterMap
FlutterMap是一个基于Flutter的在线地图插件,提供了丰富的地图数据源和交互方式,开发者可以轻松集成到自己的应用程序中。FlutterMap优秀的UI性能和地图渲染能力,为用户带来极致的滑动、缩放体验。
二、FlutterMap的使用
FlutterMap的使用十分简单,首先,在你的项目中加入flutter_map和相关依赖
dependencies:
flutter_map: ^0.12.0
flutter_map_marker_cluster: ^0.3.0
leaflet: ^1.2.0
geolocator: ^6.0.0+1
接着,初始化leaflet插件并指定地图位置和视图:
import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:latlong/latlong.dart';
void main() {
runApp(MaterialApp(
home: Scaffold(
body: FlutterMap(
options: MapOptions(
center: LatLng(51.5, -0.09),
zoom: 13.0,
),
layers: [
TileLayerOptions(
urlTemplate: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
subdomains: ['a', 'b', 'c'],
),
],
),
),
));
}
以上代码使用了OpenStreetMaps地图数据,可以切换为谷歌地图等其他在线地图数据源,在TileLayerOptions中设置即可。
三、FlutterMap的高级应用
1、地图标记
FlutterMap提供了多种标记的类型和自定义功能,支持在地图上添加自定义标记,实现定制化的描点效果。例如,我们可以通过FlutterMapMarkerCluster扩展插件实现聚合标记效果:
import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:flutter_map_marker_cluster/flutter_map_marker_cluster.dart';
import 'package:latlong/latlong.dart';
void main() {
var markers = [
Marker(
width: 80.0,
height: 80.0,
point: LatLng(51.5, -0.09),
builder: (ctx) => FlutterLogo()),
//...
];
runApp(MaterialApp(
home: Scaffold(
body: FlutterMap(
options: MapOptions(
center: LatLng(51.5, -0.09),
zoom: 13.0,
),
layers: [
TileLayerOptions(
urlTemplate: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
subdomains: ['a', 'b', 'c'],
),
MarkerClusterLayerOptions(
maxClusterRadius: 120,
size: Size(40, 40),
markers: markers,
polygonOptions: PolygonOptions(
borderColor: Colors.blueAccent,
color: Colors.black12,
borderStrokeWidth: 3),
clusterBuilder: (BuildContext context, LatLng latLng,
List markers) {
return Container();
},
),
],
),
),
));
}
2、地图交互
FlutterMap提供了多种地图交互方式,包括拖拽、缩放、双击、长按等操作。其中,地图缩放的实现方式非常简单,只需要在MapOptions中设置minZoom和maxZoom即可实现地图缩放范围的限制,在此基础上加入手势检测来实现手势缩放效果:
import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:latlong/latlong.dart';
void main() {
var controller = MapController();
var minZoom = 10.0;
var maxZoom = 19.0;
var initialZoom = 11.0;
var center = LatLng(51.5, -0.09);
void onChangedMapZoom() {
if (controller.zoom <= minZoom) {
controller.move(center, minZoom);
} else if (controller.zoom >= maxZoom) {
controller.move(center, maxZoom);
}
}
runApp(MaterialApp(
home: Scaffold(
body: GestureDetector(
child: FlutterMap(
mapController: controller,
options: MapOptions(
center: center,
zoom: initialZoom,
onPositionChanged: (_) => onChangedMapZoom(),
minZoom: minZoom,
maxZoom: maxZoom,
),
layers: [
TileLayerOptions(
urlTemplate: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
subdomains: ['a', 'b', 'c'],
),
],
),
onScaleStart: (_) {
controller.drag(false);
},
onScaleUpdate: (ScaleUpdateDetails details) {
var zoom = controller.zoom - details.scale + 1;
controller.move(details.focal, zoom);
},
onScaleEnd: (_) {
controller.drag(true);
},
),
),
));
}
3、实时导航
FlutterMap提供了路线规划和导航的功能,支持路径规划和实时导航的实现。下面展示了如何使用FlutterMap和geolocator插件实现实时导航:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:geolocator/geolocator.dart';
import 'package:latlong/latlong.dart';
void main() {
runApp(MaterialApp(home: Scaffold(body: NavigationMap())));
}
class NavigationMap extends StatefulWidget {
@override
_NavigationMapState createState() => _NavigationMapState();
}
class _NavigationMapState extends State {
var _positionStream = StreamController();
@override
void initState() {
Geolocator.getPositionStream().listen((position) {
_positionStream.add(LatLng(position.latitude, position.longitude));
});
super.initState();
}
@override
dispose() {
_positionStream.close();
super.dispose();
}
@override
Widget build(BuildContext context) {
return FlutterMap(
options: MapOptions(
center: LatLng(51.5, -0.09),
zoom: 13.0,
),
layers: [
TileLayerOptions(
urlTemplate: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
subdomains: ['a', 'b', 'c'],
),
PolylineLayerOptions(
polylines: [
Polyline(
points: _positionStream.stream,
color: Colors.redAccent,
),
],
),
MarkerLayerOptions(
markers: [
Marker(
width: 80.0,
height: 80.0,
point: LatLng(51.5, -0.09),
builder: (ctx) => Icon(Icons.location_on),
),
],
),
],
);
}
}
四、总结
FlutterMap提供了对地图相关的一些丰富操作,使用FlutterMap可以帮助开发者轻松并高效地开发地图交互相关的应用。