Flutter Map中Polyline在用户离开建筑时未消失的问题
问题修复:Flutter Map Polyline 未根据用户位置自动隐藏
核心问题分析
- 位置状态检查仅在
getUserPositionStream初始化时执行一次,用户位置更新后未重新判断是否在建筑范围内 - WebSocket接收坐标后直接添加Polyline,未验证用户当前是否在目标建筑区域内
polylines列表更新逻辑不严谨,导致旧Polyline残留显示
具体修复步骤
1. 重构位置监听逻辑,实时检查用户位置状态
修改map_view_model.dart中的getUserPositionStream方法,将位置检查逻辑移至位置流的监听回调中,确保每次位置更新都执行判断:
getUserPositionStream() async { var locationOptions = const LocationSettings(accuracy: LocationAccuracy.high, distanceFilter: 0); Geolocator.getPositionStream(locationSettings: locationOptions).listen((Position position) { if (this.position != position) { this.position = position; accuracy = position.accuracy; _updateMarker(); // 每次位置更新时检查是否在当前Polyline范围内 _checkUserLocationInPolyline(); createMapLayers(); notifyListeners(); } }); // 初始化时发送一次位置请求建筑数据 String latLonString = '${position!.longitude},${position!.latitude}'; channel.sink.add(latLonString); } // 新增方法:检查用户是否在Polyline范围内并更新状态 void _checkUserLocationInPolyline() { if (polylineCoordinates.isEmpty) return; bool isInPolylines = MapUtil.containsLocation( LatLng(position!.latitude, position!.longitude), polylineCoordinates, false ); if (!isInPolylines) { polylineCoordinates.clear(); polylines.clear(); notifyListeners(); // 发送当前位置请求新的建筑Polyline String latLonString = '${position!.longitude},${position!.latitude}'; channel.sink.add(latLonString); } }
2. 修改WebSocket数据接收逻辑,添加位置验证
在map_view.dart的StreamBuilder中,接收坐标后先判断用户是否在该建筑范围内,再决定是否更新Polyline:
StreamBuilder( stream: viewModel.channel.stream, builder: (context, snapshot) { if (snapshot.hasData) { Map<String, dynamic> data = json.decode(snapshot.data); List<dynamic> coordinates = data['coordinates'][0]; List<LatLng> newPolylineCoords = []; for (var coordinate in coordinates) { double longitude = coordinate[0]; double latitude = coordinate[1]; newPolylineCoords.add(LatLng(latitude, longitude)); } // 检查当前用户是否在新接收的建筑范围内 bool isInNewBuilding = MapUtil.containsLocation( LatLng(viewModel.position!.latitude, viewModel.position!.longitude), newPolylineCoords, false ); if (isInNewBuilding) { viewModel.polylineCoordinates.clear(); viewModel.polylineCoordinates.addAll(newPolylineCoords); viewModel.polylines.clear(); viewModel._buildPolylines(viewModel.polylineCoordinates); viewModel.notifyListeners(); } else { // 用户不在该建筑内,清空Polyline viewModel.polylineCoordinates.clear(); viewModel.polylines.clear(); viewModel.notifyListeners(); } return const Align( alignment: Alignment.bottomCenter, child: Text('data Received',style: TextStyle(color: Colors.white,decoration: TextDecoration.none,fontSize: 10.0),) ); } else if (snapshot.hasError) { return const Text('Error'); } else { viewModel.polylineCoordinates.clear(); viewModel.polylines.clear(); return const Text(''); } }, ),
3. 优化_buildPolylines方法,避免重复添加
确保每次构建Polyline前先清空列表:
List<Polyline> _buildPolylines(List<LatLng> polylineCoordinates) { polylines.clear(); // 清空旧Polyline,避免重复添加 if (polylineCoordinates.isEmpty) return polylines; Polyline polyline = Polyline( points: polylineCoordinates, color: Colors.yellow, strokeWidth: 2, ); polylines.add(polyline); return polylines; }
4. 修正createMapLayers中的Polyline层逻辑
只有当polylines不为空时才添加到图层:
createMapLayers() { mapLayers.clear(); mapLayers.addAll([ TileLayerOptions( urlTemplate: 'http://mt3.google.com/vt/lyrs=s&x={x}&y={y}&z={z}', subdomains: ['a', 'b', 'c'], maxZoom: 20 ), MarkerLayerOptions( markers: [ Marker( point: LatLng(position!.latitude, position!.longitude), builder: (context)=> RotationMarker( rotation: compassHeading, builder: (context)=> Stack( children: [ const Icon(Icons.tornado_sharp,size: 30,color: Colors.lightBlue,), Positioned( top:10,left: 4.1,bottom:0, child: Image.asset( "assets/images/current_location_gif.gif", ), ) ], ), color: Colors.blue, size: 50.0, ) ), ] ), PolygonLayerOptions( polygons: [ Polygon( points: _createCirclePoints(LatLng(position!.latitude, position!.longitude), 0.001), color: Colors.blue.withOpacity(0.2), borderColor: Colors.transparent, ), ], ), ]); // 仅在有Polyline数据时添加图层 if (polylines.isNotEmpty) { mapLayers.add(PolylineLayerOptions(polylines: polylines)); } }
内容的提问来源于stack exchange,提问作者Soumya Manthri
相关产品推荐
相关产品推荐

