Flutter地图点聚合插件clustering_google_maps的使用
插件简介
clustering_google_maps 是一个用于在 Flutter 中实现 Google 地图点聚合功能的插件。它通过将大量的点聚合成更少的聚合点来优化地图性能。
下图展示了该插件的效果:
开发者预览状态
该插件实现了在 Google 地图上的聚类技术。它支持两种数据处理方式:
- 数据库方式(DB TECHNIQUE):从 SQLite 数据库中读取数据。
- 内存方式(MEMORY TECHNIQUE):直接使用内存中的数据列表。
使用方法
添加依赖
在 pubspec.yaml
文件中添加以下依赖项:
dependencies:
clustering_google_maps: ^版本号
然后运行 flutter pub get
安装依赖。
快速开始
数据库方式(DB TECHNIQUE)
初始化
在数据库方式下,你需要确保点的数据存储在 SQLite 数据库中,并包含以下三个字段:
- 纬度 (
latitude
) - 经度 (
longitude
) - geohash 字符串
如果尚未保存 geohash,建议安装 geohash 插件并将其保存到数据库中。
初始化时使用 ClusteringHelper.forDB
构造函数:
import 'package:clustering_google_maps/clustering_google_maps.dart';
ClusteringHelper clusteringHelper = ClusteringHelper.forDB(
dbGeohashColumn: 'geohash', // 数据库中 geohash 字段名
dbLatColumn: 'latitude', // 数据库中纬度字段名
dbLongColumn: 'longitude', // 数据库中经度字段名
dbTable: 'your_table_name', // 数据库表名
updateMarkers: updateMarkers, // 更新标记的回调
aggregationSetup: AggregationSetup(), // 聚合设置
);
更新地图
在地图创建完成后调用 updateMap()
方法更新地图:
void _onMapCreated(GoogleMapController mapController) {
clusteringHelper.mapController = mapController;
clusteringHelper.updateMap();
}
内存方式(MEMORY TECHNIQUE)
初始化
在内存方式下,你需要一个包含 LatLngAndGeohash
对象的列表。LatLngAndGeohash
是一个简单的对象,包含位置和 geohash 属性,后者会自动生成。
初始化时使用 ClusteringHelper.forMemory
构造函数:
ClusteringHelper clusteringHelper = ClusteringHelper.forMemory(
list: yourListOfLatLngAndGeohash, // 包含 LatLngAndGeohash 对象的列表
updateMarkers: updateMarkers, // 更新标记的回调
aggregationSetup: AggregationSetup(markerSize: 150), // 聚合设置
);
更新地图
同样,在地图创建完成后调用 updateMap()
方法更新地图:
void _onMapCreated(GoogleMapController mapController) {
clusteringHelper.mapController = mapController;
clusteringHelper.updateMap();
}
完整示例代码
以下是一个完整的示例代码,展示了如何使用 clustering_google_maps
插件:
import 'package:example/app_db.dart';
import 'package:example/fake_point.dart';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:clustering_google_maps/clustering_google_maps.dart';
class HomeScreen extends StatefulWidget {
final List<LatLngAndGeohash> list;
HomeScreen({Key key, this.list}) : super(key: key);
[@override](/user/override)
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
ClusteringHelper clusteringHelper;
final CameraPosition initialCameraPosition =
CameraPosition(target: LatLng(0.000000, 0.000000), zoom: 0.0);
Set<Marker> markers = Set();
void _onMapCreated(GoogleMapController mapController) async {
print("onMapCreated");
clusteringHelper.mapController = mapController;
if (widget.list == null) {
clusteringHelper.database = await AppDatabase.get().getDb();
}
clusteringHelper.updateMap();
}
updateMarkers(Set<Marker> markers) {
setState(() {
this.markers = markers;
});
}
[@override](/user/override)
void initState() {
if (widget.list != null) {
initMemoryClustering();
} else {
initDatabaseClustering();
}
super.initState();
}
// 初始化数据库方式
initDatabaseClustering() {
clusteringHelper = ClusteringHelper.forDB(
dbGeohashColumn: FakePoint.dbGeohash,
dbLatColumn: FakePoint.dbLat,
dbLongColumn: FakePoint.dbLong,
dbTable: FakePoint.tblFakePoints,
updateMarkers: updateMarkers,
aggregationSetup: AggregationSetup(),
);
}
// 初始化内存方式
initMemoryClustering() {
clusteringHelper = ClusteringHelper.forMemory(
list: widget.list,
updateMarkers: updateMarkers,
aggregationSetup: AggregationSetup(markerSize: 150),
);
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Clustering Example"),
),
body: GoogleMap(
onMapCreated: _onMapCreated,
initialCameraPosition: initialCameraPosition,
markers: markers,
onCameraMove: (newPosition) =>
clusteringHelper.onCameraMove(newPosition, forceUpdate: false),
onCameraIdle: clusteringHelper.onMapIdle,
),
floatingActionButton: FloatingActionButton(
child:
widget.list == null ? Icon(Icons.content_cut) : Icon(Icons.update),
onPressed: () {
if (widget.list == null) {
// 测试 WHERE 子句
clusteringHelper.whereClause = "WHERE ${FakePoint.dbLat} > 42.6";
}
// 强制更新地图
clusteringHelper.updateMap();
},
),
);
}
}
更多关于Flutter地图点聚合插件clustering_google_maps的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter地图点聚合插件clustering_google_maps的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
clustering_google_maps
是一个用于在 Flutter 中使用 Google Maps 进行点聚合的插件。它可以帮助你在大量标记点的情况下,将相近的点聚合在一起,以提高地图的可读性和性能。
安装插件
首先,你需要在 pubspec.yaml
文件中添加 clustering_google_maps
插件的依赖:
dependencies:
flutter:
sdk: flutter
clustering_google_maps: ^1.0.0
然后运行 flutter pub get
来安装插件。
基本使用
-
导入插件:
在你的 Dart 文件中导入
clustering_google_maps
插件:import 'package:clustering_google_maps/clustering_google_maps.dart';
-
创建地图:
使用
GoogleMap
组件来创建地图,并设置markers
属性来显示标记点。import 'package:flutter/material.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:clustering_google_maps/clustering_google_maps.dart'; class MapScreen extends StatefulWidget { [@override](/user/override) _MapScreenState createState() => _MapScreenState(); } class _MapScreenState extends State<MapScreen> { late GoogleMapController mapController; final Set<Marker> markers = {}; [@override](/user/override) void initState() { super.initState(); _loadMarkers(); } void _loadMarkers() async { final List<ClusterItem> items = [ ClusterItem(LatLng(37.7749, -122.4194), 'San Francisco'), ClusterItem(LatLng(34.0522, -118.2437), 'Los Angeles'), ClusterItem(LatLng(36.1699, -115.1398), 'Las Vegas'), // 添加更多标记点 ]; final clusterManager = ClusterManager<ClusterItem>(items, _updateMarkers); await clusterManager.setMap(mapController); } void _updateMarkers(Set<Marker> markers) { setState(() { this.markers.clear(); this.markers.addAll(markers); }); } [@override](/user/override) Widget build(BuildContext context) { return Scaffold( body: GoogleMap( onMapCreated: (GoogleMapController controller) { mapController = controller; }, initialCameraPosition: CameraPosition( target: LatLng(37.7749, -122.4194), zoom: 10, ), markers: markers, ), ); } }
-
处理聚合:
ClusterManager
负责处理标记点的聚合。你需要将标记点列表传递给ClusterManager
,并提供一个回调函数_updateMarkers
来更新地图上的标记。final clusterManager = ClusterManager<ClusterItem>(items, _updateMarkers); await clusterManager.setMap(mapController);
-
自定义聚合标记:
你可以自定义聚合标记的外观。例如,可以设置聚合标记的颜色、大小和文本。
final clusterManager = ClusterManager<ClusterItem>( items, _updateMarkers, markerBuilder: (Cluster<ClusterItem> cluster) { return Marker( markerId: MarkerId(cluster.getId()), position: cluster.location, icon: BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueRed), infoWindow: InfoWindow(title: 'Cluster ${cluster.size}'), ); }, );
完整示例
以下是一个完整的示例,展示了如何使用 clustering_google_maps
插件在 Google Maps 上进行点聚合:
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:clustering_google_maps/clustering_google_maps.dart';
class MapScreen extends StatefulWidget {
[@override](/user/override)
_MapScreenState createState() => _MapScreenState();
}
class _MapScreenState extends State<MapScreen> {
late GoogleMapController mapController;
final Set<Marker> markers = {};
[@override](/user/override)
void initState() {
super.initState();
_loadMarkers();
}
void _loadMarkers() async {
final List<ClusterItem> items = [
ClusterItem(LatLng(37.7749, -122.4194), 'San Francisco'),
ClusterItem(LatLng(34.0522, -118.2437), 'Los Angeles'),
ClusterItem(LatLng(36.1699, -115.1398), 'Las Vegas'),
// 添加更多标记点
];
final clusterManager = ClusterManager<ClusterItem>(
items,
_updateMarkers,
markerBuilder: (Cluster<ClusterItem> cluster) {
return Marker(
markerId: MarkerId(cluster.getId()),
position: cluster.location,
icon: BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueRed),
infoWindow: InfoWindow(title: 'Cluster ${cluster.size}'),
);
},
);
await clusterManager.setMap(mapController);
}
void _updateMarkers(Set<Marker> markers) {
setState(() {
this.markers.clear();
this.markers.addAll(markers);
});
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
body: GoogleMap(
onMapCreated: (GoogleMapController controller) {
mapController = controller;
},
initialCameraPosition: CameraPosition(
target: LatLng(37.7749, -122.4194),
zoom: 10,
),
markers: markers,
),
);
}
}
void main() {
runApp(MaterialApp(
home: MapScreen(),
));
}