如何合并Firestore两个集合的Marker数据为单列表在谷歌地图展示
实现方案
你可以通过统一的存储结构合并两类Marker,推荐优先使用Map<MarkerId, Marker>结构存储所有Marker,可自动避免ID重复问题,也可以随时转换为List使用。
步骤1:定义统一存储变量
替换原有的busmarkers和busStop两个独立存储结构,定义全局统一的Marker存储变量:
// 统一存储所有Marker,Key为唯一标识MarkerId,Value为对应Marker实例 Map<MarkerId, Marker> allMarkers = <MarkerId, Marker>{};
步骤2:修改markers集合的写入逻辑
将原来写入busmarkers的逻辑改为写入allMarkers,同时增加旧数据清理逻辑,避免Firestore推送更新后出现重复Marker:
void initMarker(specify, specifyId) async{ var markerIdVal = specifyId; final MarkerId markerId = MarkerId(markerIdVal); final Marker marker = Marker( markerId: markerId, icon: BitmapDescriptor.fromAsset("assets/images/markerIconBus.png"), position: LatLng(specify['location'].latitude, specify['location'].longitude), onTap: openInfo, ); setState(() { allMarkers[markerId] = marker; }); } Future <void> getMarker() async{ Firestore.instance.collection('markers').snapshots().listen((myData) { // 先清空当前存储的所有站点类Marker,避免重复 allMarkers.removeWhere((key, value) => value.icon == BitmapDescriptor.fromAsset("assets/images/markerIconBus.png") ); if(myData.documents.isNotEmpty){ for (int i = 0; i < myData.documents.length; i++){ initMarker(myData.documents[i].data, myData.documents[i].documentID); } } }); }
步骤3:修改locations集合的写入逻辑
将原来写入busStop的逻辑改为写入allMarkers,同时修复原逻辑中MarkerId写死的问题,避免多辆巴士的Marker互相覆盖:
Firestore.instance .collection('locations') .snapshots() .listen((driverLocation){ // 先清空当前存储的所有巴士类Marker,避免重复 allMarkers.removeWhere((key, value) => value.icon == BitmapDescriptor.fromAsset("assets/images/bus.png") ); driverLocation.documents.forEach((dLocation){ double latitudeD = dLocation.data['latitude']; double longitudeD = dLocation.data['longitude']; // 使用locations集合的文档ID作为MarkerId,保证唯一 final MarkerId markerId = MarkerId(dLocation.documentID); allMarkers[markerId] = Marker( markerId: markerId, draggable: false, icon: BitmapDescriptor.fromAsset("assets/images/bus.png"), onTap: () {}, position: LatLng(latitudeD, longitudeD), ); }); setState(() {}); });
步骤4:地图渲染使用统一Marker集合
谷歌地图组件的markers参数直接传入统一集合的value即可,如需List格式,直接调用toList()方法转换:
GoogleMap( // 其余地图配置省略 markers: Set<Marker>.of(allMarkers.values), ) // 如需获得合并后的List<Marker>,直接转换即可 List<Marker> mergedMarkerList = allMarkers.values.toList();
注意事项
- 每次Firestore推送快照更新时,先清理对应类型的旧Marker,避免数据变更后残留无效标记
- 所有Marker的MarkerId必须唯一,否则会出现后添加的Marker覆盖已有Marker的问题
- 如需区分两类Marker做不同的交互逻辑,可以通过Marker的icon属性、infoWindow属性做判断
内容的提问来源于stack exchange,提问作者randomstudent
相关产品推荐
相关产品推荐

